/*
 * Copyright (C) 2006 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.content;

import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.StringDef;
import android.annotation.SystemApi;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.res.AssetManager;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.database.DatabaseErrorHandler;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
import android.graphics.Bitmap;
import android.graphics.drawable.Drawable;
import android.media.MediaScannerConnection.OnScanCompletedListener;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Looper;
import android.os.StatFs;
import android.os.UserHandle;
import android.os.UserManager;
import android.provider.MediaStore;
import android.util.AttributeSet;
import android.view.DisplayAdjustments;
import android.view.Display;
import android.view.ViewDebug;
import android.view.WindowManager;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

/**
 * 与应用程序环境的全局信息的接口。 这是一个抽象类，其实现由Android系统提供。
 * 它允许访问特定于应用程序的资源和类，以及对诸如启动活动，广播和接收意图等应用程序级操作的回调。
 */
public abstract class Context {
    /**
     * 文件创建模式：默认模式，创建的文件只能由调用应用程序访问（或共享相同用户ID的所有应用程序）。
     * mode private
     */
    public static final int MODE_PRIVATE = 0x0000;
    /**
     * @deprecated 创建全局可读的文件是非常危险的，并可能在应用程序中造成安全漏洞。
     * 强烈不鼓励; 相反，应用程序应该使用更正式的交互机制，
     * 如{@link ContentProvider}，{@link BroadcastReceiver}和{@link android.app.Service}。
     * 无法保证此访问模式将保留在文件中，例如当它经历备份和恢复时。
     *
     * 件创建模式：允许所有其他应用程序具有对创建文件的读取访问权限。
     * mode world readable
     */
    @Deprecated
    public static final int MODE_WORLD_READABLE = 0x0001;
    /**
     * @deprecated 创建全部可写文件是非常危险的，并且很可能会在应用程序中造成安全漏洞。
     * 强烈不鼓励; 相反，应用程序应该使用更正式的交互机制，如{@link ContentProvider}，{@link BroadcastReceiver}和
     * {@link android.app.Service}。 无法保证此访问模式将保留在文件中，例如当它经历备份和恢复时。
     *
     * 文件创建模式：允许所有其他应用程序对创建的文件具有写入权限。
     * mode world writeable
     */
    @Deprecated
    public static final int MODE_WORLD_WRITEABLE = 0x0002;
    /**
     * 文件创建模式：用于{@link #openFileOutput}，如果文件已经存在，
     * 则将数据写入现有文件的末尾而不是将其擦除。
     * @see #openFileOutput
     * mode append
     */
    public static final int MODE_APPEND = 0x8000;

    /**
     * 共享首选项加载标志：设置时，即使共享首选项实例已在此进程中加载​​，也将检查磁盘上的文件以进行修改。
     * 如果应用程序有多个进程，并且都写入相同的共享首选项文件，则有时需要此行为。 
     * 不过，通常在流程之间有更好的交流形式。
     *
     * 这是Gingerbread（Android 2.3）之前和之前的传统（但没有记录）行为，并且此标志在定位此类发行版时隐含。
     * 对于目标SDK版本大于Android 2.3的应用程序，必须根据需要明确设置此标志。
     *
     * @see #getSharedPreferences
     * mode multi process
     */
    public static final int MODE_MULTI_PROCESS = 0x0004;

    /**
     * 数据库打开标志：设置时，默认情况下启用预写日志记录打开数据库。
     *
     * @see #openOrCreateDatabase(String, int, CursorFactory)
     * @see #openOrCreateDatabase(String, int, CursorFactory, DatabaseErrorHandler)
     * @see SQLiteDatabase#enableWriteAheadLogging
     * mode enable write ahead logging:模式启用预写日志
     */
    public static final int MODE_ENABLE_WRITE_AHEAD_LOGGING = 0x0008;



    /**
     * {@link #bindService}的标志：只要绑定存在，就自动创建服务。
     * 请注意，虽然这将创建该服务，但它的{@link android.app.Service#onStartCommand}
     * 仍然只能通过{@link #startService}显式调用。
     *bind auto carate
     */
    public static final int BIND_AUTO_CREATE = 0x0001;
    /**
     * 用于{@link #bindService}的标志：包含调试帮助，用于调配不匹配的调用。
     * 如果设置了此标志，则保留以下{@link #unbindService}调用的调用堆栈，
     * 以便在稍后执行不正确的取消绑定调用时进行打印。
     * 请注意，执行此操作需要保留有关应用程序生命周期的绑定的信息，从而导致泄漏 - 这应仅用于调试。
     * bind debug unbind
     */
    public static final int BIND_DEBUG_UNBIND = 0x0002;



    /**
     * {@link #bindService}的标记：不允许此绑定将目标服务的进程提升为前台调度优先级。
     * 它仍然会被提升到至少与客户端相同的内存优先级（这样它的进程在任何客户端不能被利用的情况下都不会被利用），
     * 但是为了CPU调度的目的，它可能被留在后台。 这只会在绑定客户端是前台进程而目标服务处于后台进程的情况下产生影响。
     * bind not foreground
     */
    public static final int BIND_NOT_FOREGROUND = 0x0004;

    /**
     * {@link #bindService}的标志：表示绑定到此服务的客户端应用程序认为该服务比应用程序本身更重要。
     * 设置后，平台将尝试让内存不足杀手杀死应用程序，然后再杀死绑定的服务，尽管这并不能保证。
     * bind above client
     */
    public static final int BIND_ABOVE_CLIENT = 0x0008;

    /**
     * {@link #bindService}标志：允许承载绑定服务的进程通过其正常的内存管理。
     * 它将被视为更像是一个正在运行的服务，允许系统（暂时）清除进程，如果内存不足或其他可能存在的奇想，
     * 并且更积极地使其成为可能被杀死（并重新启动）的候选者如果运行很长时间。
     * bind allow oom management
     */
    public static final int BIND_ALLOW_OOM_MANAGEMENT = 0x0010;

    /**
     * {@link #bindService}的标志：不影响目标服务主机进程的调度或内存管理优先级。
     * 允许服务的进程在后台LRU列表上进行管理，就像后台的常规应用程序进程一样。
     * bind waive priority
     */
    public static final int BIND_WAIVE_PRIORITY = 0x0020;
    /** @hide */
    @IntDef(flag = true,
            value = {
                    BIND_AUTO_CREATE,
                    BIND_AUTO_CREATE,
                    BIND_DEBUG_UNBIND,
                    BIND_NOT_FOREGROUND,
                    BIND_ABOVE_CLIENT,
                    BIND_ALLOW_OOM_MANAGEMENT,
                    BIND_WAIVE_PRIORITY
            })
    @Retention(RetentionPolicy.SOURCE)
    public @interface BindServiceFlags {}

    /**
     * {@link #bindService}的标志：这个服务对于客户端来说非常重要，所以当客户端时应该被带到前台进程级别。
     * 通常情况下，客户端只能将进程提升到可见性级别，即使该客户端位于前台。
     * bind important
     */
    public static final int BIND_IMPORTANT = 0x0040;

    /**
     * {@link #bindService}的标志：如果绑定来自某个活动，则允许根据用户是否可以看到活动来提高目标服务的进程重要性，
     * 而不管是否使用另一个标志来减少客户端进程的数量 整体重要性被用来影响它。
     * bind adjusy with activity
     */
    public static final int BIND_ADJUST_WITH_ACTIVITY = 0x0080;

    /**
     * @hide {@link #bindService}的标志：将绑定视为托管活动，将绑定视为在后台进行的活动。
     * 也就是说，解除绑定时，进程在空的时候会进入活动LRU列表而不是常规进程，从而使其更加激进。
     * 这是为了与IME一起使用，以尽量保持IME过程的快速键盘切换。
     * bind treat like activity
     */
    public static final int BIND_TREAT_LIKE_ACTIVITY = 0x08000000;

    /**
     * @hide 一个尚未实现的想法。 用于{@link #bindService}:的标志：
     * 如果从活动绑定，则认为该服务像绑定活动一样可见。 也就是说，它将被视为比无形背景活动更重要的东西。
     * 这将影响用户可以在不重新启动的情况下切换的最近活动的数量。
     * 无法保证这将得到尊重，因为系统试图平衡来自一个应用程序的这种请求与保留其他应用程序的重要性。
     * bind visible
     */
    public static final int BIND_VISIBLE = 0x10000000;

    /**
     * @hide 用于{@link #bindService}的标志：考虑这种绑定会导致目标进程显示UI，因此它会在UI_HIDDEN内存修剪消失时执行
     * bind showing UI
     */
    public static final int BIND_SHOWING_UI = 0x20000000;

    /**
     * @hide  {@link #bindService}的标志：即使调用者可见，也不要将绑定服务视为可见。
     * bind not visible
     */
    public static final int BIND_NOT_VISIBLE = 0x40000000;

    /** 为您的应用程序包返回一个Asset Manager实例。*/
    public abstract AssetManager getAssets();

    /** 为您的应用程序包返回一个Resources实例。 */
    public abstract Resources getResources();

    /** 返回PackageManager实例以查找全局包信息*/
    public abstract PackageManager getPackageManager();

    /** 您的应用程序包返回一个ContentResolver实例。 */
    public abstract ContentResolver getContentResolver();

    /**
     * 返回当前进程主线程的Looper。 这是用于调用应用程序组件（活动，服务等）的线程。
     * 根据定义，此方法返回与通过调用{@link Looper#getMainLooper() Looper.getMainLooper()}.所获得的结果相同的结果。
     *
     * @return The main looper.
     */
    public abstract Looper getMainLooper();

    /**
     * 返回当前进程的单个全局应用程序对象的上下文。 这通常只应用于需要生命周期与当前上下文分离的Context，该生命周期与进程的生命周期相关，而不是当前组件。
     *
     * 例如，考虑它如何与 {@link #registerReceiver(BroadcastReceiver, IntentFilter)}交互
     *
     *
     * 如果从Activity上下文中使用，接收者正在该活动中注册。 这意味着您需要在活动完成之前取消注册;
     * 事实上，如果你不这样做，框架会清除你的泄漏注册，因为它会删除活动并记录错误。
     * 因此，如果使用Activity上下文来注册一个静态的接收者（对进程是全局的，而不是与一个Activity实例关联的），
     * 那么在你使用的活动被销毁的任何点上，你的注册将被删除。
     *
     * 如果从此处返回的Context使用，则接收者正在注册与您的应用程序关联的全局状态。
     * 因此它永远不会被注销。 如果接收器与静态数据相关联，而不是特定组件，则这是必要的。
     * 但是，如果您忘记取消注册，取消绑定等操作，则在别处使用应用程序上下文可能会导致严重泄漏
     * 
     */
    public abstract Context getApplicationContext();

    /**
     * 在Context的基本应用程序中添加一个新的{@link ComponentCallbacks}，它
     * 将在调用ComponentCallbacks方法和其他组件的同时被调用。
     * 请注意，您将来必须确保在适当的时候使用{@link #unregisterComponentCallbacks} ; 这不会被删除。
     *
     * @param callback 调用的接口。 这可以是一个{@link ComponentCallbacks} or {@link ComponentCallbacks2} interface.
     */
    public void registerComponentCallbacks(ComponentCallbacks callback) {
        getApplicationContext().registerComponentCallbacks(callback);
    }

    /**
     * 删除之前使用 {@link ComponentCallbacks}注册的{@link #registerComponentCallbacks(ComponentCallbacks)}对象。
     */
    public void unregisterComponentCallbacks(ComponentCallbacks callback) {
        getApplicationContext().unregisterComponentCallbacks(callback);
    }

    /**
     * 从应用程序包的默认字符串表中返回一个本地化的，样式化的Char序列。
     *
     * @param resId 字符序列文本的资源ID
     */
    public final CharSequence getText(int resId) {
        return getResources().getText(resId);
    }

    /**
     * 从应用程序包的默认字符串表中返回一个本地化的字符串。
     *
     * @param resId 该字符串的资源ID
     */
    public final String getString(int resId) {
        return getResources().getString(resId);
    }

    /**
     * 从应用程序的包的默认字符串表中返回一个本地化的格式化字符串，
     * 替换{@link java.util.Formatter} and {@link java.lang.String#format}。
     *
     * @param resId 格式字符串的资源ID
     * @param formatArgs 将用于替换的格式参数。
     */

    public final String getString(int resId, Object... formatArgs) {
        return getResources().getString(resId, formatArgs);
    }

    /**
     * 返回与特定资源ID关联的可绘制对象，并为当前主题进行样式设置。
     *
     * @param id 所需的资源标识符，由aapt工具生成。 此整数对包，类型和资源条目进行编码。 值0是无效的标识符。
     * @return 可绘制可用于绘制此资源的对象。
     */
    public final Drawable getDrawable(int id) {
        return getResources().getDrawable(id, getTheme());
    }

     /**
      * 为此上下文设置基本主题。 请注意，应该在Context中实例化任何视图之前调用它
      * （例如在调用{@link android.app.Activity#setContentView}或{@link android.view.LayoutInflater#inflate}之前）。
     *
     * @param resid 描述主题的样式资源。
     */
    public abstract void setTheme(int resid);

    /** @hide 需要一些内部实现...不公开，因为你不能认为这实际上意味着什么。 */
    public int getThemeResId() {
        return 0;
    }

    /**
     * 返回与此上下文关联的主题对象。
     */
    @ViewDebug.ExportedProperty(deepExport = true)
    public abstract Resources.Theme getTheme();

    /**
     * 在此Context的主题中检索样式化属性信息。
     * 请参阅{@link Resources.Theme#obtainStyledAttributes(int[])}以获取更多信息。
     *
     * @see Resources.Theme#obtainStyledAttributes(int[])
     */
    public final TypedArray obtainStyledAttributes(
            int[] attrs) {
        return getTheme().obtainStyledAttributes(attrs);
    }

    /**
     * 在此Context的主题中检索样式化属性信息。 请参阅{@link Resources.Theme#obtainStyledAttributes(int, int[])}以获取更多信息。
     *
     * @see Resources.Theme#obtainStyledAttributes(int, int[])
     */
    public final TypedArray obtainStyledAttributes(
            int resid, int[] attrs) throws Resources.NotFoundException {
        return getTheme().obtainStyledAttributes(resid, attrs);
    }

    /**
     * 在此Context的主题中检索样式化属性信息。 请参阅{@link Resources.Theme#obtainStyledAttributes(AttributeSet, int[], int, int)}以获取更多信息。
     *
     * @see Resources.Theme#obtainStyledAttributes(AttributeSet, int[], int, int)
     */
    public final TypedArray obtainStyledAttributes(
            AttributeSet set, int[] attrs) {
        return getTheme().obtainStyledAttributes(set, attrs, 0, 0);
    }

    /**
     * 在此Context的主题中检索样式化属性信息。
     * 请参阅{@link Resources.Theme#obtainStyledAttributes(AttributeSet, int[], int, int)}以获取更多信息。
     *
     * @see Resources.Theme#obtainStyledAttributes(AttributeSet, int[], int, int)
     */
    public final TypedArray obtainStyledAttributes(
            AttributeSet set, int[] attrs, int defStyleAttr, int defStyleRes) {
        return getTheme().obtainStyledAttributes(
            set, attrs, defStyleAttr, defStyleRes);
    }

    /**
     * 返回一个你可以用来检索这个包中的类的类加载器。
     */
    public abstract ClassLoader getClassLoader();

    /** 返回此应用程序包的名称*/
    public abstract String getPackageName();

    /** @hide 返回此上下文所来源的基础上下文的名称。*/
    public abstract String getBasePackageName();

    /** @hide 从这个上下文返回应该用于应用操作调用的包名称。 这与{@link #getBasePackageName()}相同，除非系统组件被加载到其他应用程序进程中，
     * 在这种情况下，这将是该进程中的主要软件包的名称（以便app ops uid 验证将与名称一起工作）。*/
    public abstract String getOpPackageName();

    /** 返回此上下文包的完整应用程序信息。*/
    public abstract ApplicationInfo getApplicationInfo();

    /**
     * 回此上下文的主要Android包的完整路径。 Android包是一个包含应用程序主要资源的ZIP文件。
     *
     * 注意：这对于应用程序通常不是很有用，因为它们不应该直接访问文件系统。
     *
     * @return String 资源的路径。
     */
    public abstract String getPackageResourcePath();

    /**
     * 返回此上下文的主要Android包的完整路径。 Android包是一个ZIP文件，其中包含应用程序的主要代码和资产。
     *
     * 注意：这对于应用程序通常不是很有用，因为它们不应该直接访问文件系统。
     *
     * @return String 代码和资产的路径。
     */
    public abstract String getPackageCodePath();

    /**
     * {@hide}
     * 为给定的prefs组名称返回共享prefs文件的完整路径
     *
     * 注意：这对于应用程序通常不是很有用，因为它们不应该直接访问文件系统。
     */
    public abstract File getSharedPrefsFile(String name);

    /**
     * 检索并保存首选项文件'name'的内容，返回一个共享首选项，通过它可以检索和修改其值。 共享首选项对象只有一个实例返回给同一名称的任何调用者，这意味着他们一旦创建就会看到对方的编辑。
     *
     * @param name 所需的首选项文件。 如果此名称的首选项文件不存在，则在您检索编辑器（Shared Preferences.edit（））并提交更改（Editor.commit（））时将创建它。
     *
     *
     * @param mode 操作模式。 默认操作 {@link #MODE_WORLD_READABLE}和{@link #MODE_WORLD_WRITEABLE} 使用0或{@link #MODE_PRIVATE} 来控制权限。
     *             如果多个进程正在改变相同的共享首选项文件，也可以使用位{@link #MODE_MULTI_PROCESS}。 {@link #MODE_MULTI_PROCESS}
     *             在针对Gingerbread（Android 2.3）及更低版本的应用中始终处于打开状态，并且在更高版本中默认为关闭。
     *
     * @return 用于检索和修改首选项值的单个{@link SharedPreferences}实例。
     *
     * @see #MODE_PRIVATE
     * @see #MODE_WORLD_READABLE
     * @see #MODE_WORLD_WRITEABLE
     * @see #MODE_MULTI_PROCESS
     */
    public abstract SharedPreferences getSharedPreferences(String name,
            int mode);

    /**
     * 打开与此Context的应用程序包关联的私人文件以供阅读。
     *
     * @param name 要打开的文件的名称; 不能包含路径分隔符。
     *
     * @return The resulting {@link FileInputStream}.
     *
     * @see #openFileOutput
     * @see #fileList
     * @see #deleteFile
     * @see java.io.FileInputStream#FileInputStream(String)
     */
    public abstract FileInputStream openFileInput(String name)
        throws FileNotFoundException;

    /**
     * 打开与此Context的应用程序包关联的私有文件以进行写入。 如果该文件不存在，则创建该文件。
     *
     * 由于它使用内部存储，因此无需调用此方法的权限。
     *
     * @param name 要打开的文件的名称; 不能包含路径分隔符。
     * @param mode 操作模式。 使用0或{@link #MODE_PRIVATE} 作为默认操作，{@link ＃MODE_APPEND}追加到现有文件，{@link ＃MODE_WORLD READABLE}和{@link ＃MODE_WORLD_WRITEABLE}来控制权限。
     *
     *
     * @return The resulting {@link FileOutputStream}.
     *
     * @see #MODE_APPEND
     * @see #MODE_PRIVATE
     * @see #MODE_WORLD_READABLE
     * @see #MODE_WORLD_WRITEABLE
     * @see #openFileInput
     * @see #fileList
     * @see #deleteFile
     * @see java.io.FileOutputStream#FileOutputStream(String)
     */
    public abstract FileOutputStream openFileOutput(String name, int mode)
        throws FileNotFoundException;

    /**
     * 删除与此Context的应用程序包关联的给定私人文件。
     *
     * @param name 要删除的文件的名称; 不能包含路径分隔符。
     *
     * @return {@code true}如果文件被成功删除; 其他{@code false}。
     *
     * @see #openFileInput
     * @see #openFileOutput
     * @see #fileList
     * @see java.io.File#delete()
     */
    public abstract boolean deleteFile(String name);

    /**
     * 返回存储使用{@link #openFileOutput}创建的文件的文件系统上的绝对路径。
     *
     * @param name 您想要获取路径的文件的名称。
     *
     * @return 给定文件的绝对路径。
     *
     * @see #openFileOutput
     * @see #getFilesDir
     * @see #getDir
     */
    public abstract File getFileStreamPath(String name);

    /**
     * 返回存储使用{@link #openFileOutput}创建的文件的文件系统上目录的绝对路径
     *
     * 读取或写入返回的路径不需要任何权限，因为此路径是内部存储器。
     *
     * @return  保存应用程序文件的目录的路径。
     *
     * @see #openFileOutput
     * @see #getFileStreamPath
     * @see #getDir
     */
    public abstract File getFilesDir();

    /**
     * 返回类似于{@link #getFilesDir()}的文件系统上目录的绝对路径。 不同之处在于放置在该目录下的文件将被排除在远程存储的自动备份之外。
     * 请参阅{@link android.app.backup.BackupAgent BackupAgent}以全面讨论Android中的自动备份机制。 读取或写入返回的路径不需要任何权限，因为此路径是内部存储器。
     *
     *
     * @return 保存应用程序文件的目录的路径不会自动备份到远程存储。 
     *
     * @see #openFileOutput
     * @see #getFileStreamPath
     * @see #getDir
     * @see android.app.backup.BackupAgent
     */
    public abstract File getNoBackupFilesDir();

    /**
     * 返回主外部文件系统上的目录的绝对路径（位于{@link android.os.Environment#getExternalStorageDirectory()
     * Environment.getExternalStorageDirectory()}）
     * 应用程序可以在其中放置持久性文件的位置 拥有。 这些文件是应用程序的内部文件，对于用户而言通常不可见为媒体。
     *
     * 这就像{@link #getFilesDir()}，因为这些文件在卸载应用程序时会被删除，但是有一些重要的区别：
     *1.外部文件并不总是可用的：如果用户将外部存储装置安装在计算机上或将其移除，它们将消失。 请参阅{@link android.os.Environment}上的API。 获取存储状态信息。
     * 2.这些文件没有执行安全措施。 例如，任何持有{@link android.Manifest.permission#WRITE_EXTERNAL_STORAGE}可以写入这些文件
     * 
     * 
     * 从{@link android.os.Build.VERSION_CODES#KITKAT}开始，读取或写入返回的路径不需要任何权限; 它始终可供调用应用程序访问。 
     * 这仅适用于为调用应用程序的包名称生成的路径。 要访问属于其他包的路径，
     * {@link android.Manifest.permission#WRITE_EXTERNAL_STORAGE}
     * and/or {@link android.Manifest.permission#READ_EXTERNAL_STORAGE}是必需的。
     *
     * 
     * 在具有多个用户的设备上（如{@link UserManager}所述），每个用户都有自己独立的外部存储。 应用程序只能访问运行用户的外部存储。
     *
     *
     * 以下是在应用程序的专用存储中操纵文件的典型代码示例：
     *
     * {@sample development/samples/ApiDemos/src/com/example/android/apis/content/ExternalStorage.java
     * private_file}
     *
     * 如果您为此函数提供非null类型，则返回的文件将成为给定类型的子目录的路径。
     * 尽管媒体扫描程序不会自动扫描这些文件，但您可以使用
     * {@link android.media.MediaScannerConnection#scanFile(Context, String[], String[],
     *      OnScanCompletedListener) MediaScannerConnection.scanFile}。
     *      媒体扫描器连接＃扫描文件（上下文，字符串[]，字符串[]，在扫描完成监听器）媒体扫描器连接。扫描文件}。
     *      请注意，这不同于{@link android.os.Environment#getExternalStoragePublicDirectory
     * Environment.getExternalStoragePublicDirectory()}，
     * 它提供所有应用程序共享的媒体目录。 这里返回的目录是应用程序所拥有的，当应用程序被卸载时，
     * 它们的内容将被删除。 不像{@link android.os.Environment#getExternalStoragePublicDirectory
     * Environment.getExternalStoragePublicDirectory()}，此处返回的目录将自动为您创建。
     *
     *
     * 以下是典型代码的示例，用于在应用程序的专用存储中操作图片并将其添加到媒体数据库中：
     *
     * {@sample development/samples/ApiDemos/src/com/example/android/apis/content/ExternalStorage.java
     * private_picture}
     *
     * @param type 要返回的文件目录的类型。 可以为文件目录的根目录或子目录的以下环境常量之一：
     * {@link android.os.Environment#DIRECTORY_MUSIC},
     * {@link android.os.Environment#DIRECTORY_PODCASTS},
     * {@link android.os.Environment#DIRECTORY_RINGTONES},
     * {@link android.os.Environment#DIRECTORY_ALARMS},
     * {@link android.os.Environment#DIRECTORY_NOTIFICATIONS},
     * {@link android.os.Environment#DIRECTORY_PICTURES}, or
     * {@link android.os.Environment#DIRECTORY_MOVIES}.
     *
     * @return 目录在外部存储器上保存应用程序文件的路径。 如果外部存储当前未安装，则返回null，因此无法确保路径存在; 当它可用时，您将需要再次调用此方法。
     *
     * @see #getFilesDir
     * @see android.os.Environment#getExternalStoragePublicDirectory
     */
    @Nullable
    public abstract File getExternalFilesDir(@Nullable String type);

    /**
     * 返回应用程序可以放置它拥有的持久性文件的所有外部存储设备上特定于应用程序的目录的绝对路径。 这些文件是应用程序的内部文件，并且通常不会作为媒体显示给用户。
     *
     * 这就像 {@link #getFilesDir()}，因为这些文件在卸载应用程序时会被删除，但是有一些重要的区别：
     * 1.外部文件并不总是可用的：如果用户将外部存储装置安装在计算机上或将其移除，它们将消失。
     * 2.这些文件没有执行安全措施
     * 
     *
     * 这里返回的外部存储设备被视为设备的永久部分，包括仿真的外部存储和物理介质插槽，如电池仓中的SD卡。
     * 返回的路径不包括瞬态设备，如USB闪存驱动器。 应用程序可以将数据存储在任何或所有返回的设备上。
     * 例如，应用可能会选择将大文件存储在具有最多可用空间的设备上，如{@link StatFs}所衡量的。
     * 读取或写入返回的路径不需要任何权限; 他们总是可以访问调用应用程序。 在辅助外部存储设备上写入这些路径之外的访问权限不可用。
     * 返回的第一个路径与{@link #getExternalFilesDir(String)}相同。 如果存储设备不可用，返回的路径可能为{@code null}
     *
     *
     * @see #getExternalFilesDir(String)
     * @see Environment#getExternalStorageState(File)
     */
    public abstract File[] getExternalFilesDirs(String type);

    /**
     * 返回此应用程序的OBB文件（如果有）可以找到的主外部存储目录。 请注意，如果应用程序没有任何OBB文件，则该目录可能不存在。
     *
     * 这就像{@link #getFilesDir()} ，因为这些文件在卸载应用程序时会被删除，但是有一些重要的区别：
     * 1.外部文件并不总是可用的：如果用户将外部存储装置安装在计算机上或将其移除，它们将消失。
     * 2.这些文件没有执行安全措施。 例如，任何持有 {@link android.Manifest.permission#WRITE_EXTERNAL_STORAGE}可以写入这些文件。
     *
     * 从{@link android.os.Build.VERSION_CODES#KITKAT}，读取或写入返回的路径不需要任何权限; 它始终可供调用应用程序访问。
     * 这仅适用于为调用应用程序的包名称生成的路径。 要访问属于其他包的路径，
     * {@link android.Manifest.permission#WRITE_EXTERNAL_STORAGE}
     * and/or {@link android.Manifest.permission#READ_EXTERNAL_STORAGE} 是必需的。
     *
     * 在具有多个用户的设备上（如{@link UserManager}所述），多个用户可能共享相同的OBB存储位置。 应用程序应确保在不同用户下运行的多个实例不会相互干扰。
     *
     */
    public abstract File getObbDir();

    /**
     * 返回应用程序的OBB文件（如果有）的所有外部存储设备上的应用程序特定目录的绝对路径。 请注意，如果应用程序没有任何OBB文件，这些目录可能不存在。
     *
     * 这就像{@link #getFilesDir()} ，因为这些文件在卸载应用程序时会被删除，但是有一些重要的区别：
     * 1.外部文件并不总是可用的：如果用户将外部存储装置安装在计算机上或将其移除，它们将消失。
     * 2.这些文件没有执行安全措施。
     * 
     * 这里返回的外部存储设备被视为设备的永久部分，包括仿真的外部存储和物理介质插槽，如电池仓中的SD卡。
     * 返回的路径不包括瞬态设备，如USB闪存驱动器。 应用程序可以将数据存储在任何或所有返回的设备上。
     * 例如，应用可能会选择将大文件存储在具有最多可用空间的设备上，如{@link StatFs}所衡量的。
     * 读取或写入返回的路径不需要任何权限; 他们总是可以访问调用应用程序。 在辅助外部存储设备上写入这些路径之外的访问权限不可用。
     * 返回的第一个路径与{@link #getObbDir()}相同。 如果存储设备不可用，返回的路径可能为{@code null}.
     *
     *
     * @see #getObbDir()
     * @see Environment#getExternalStorageState(File)
     */
    public abstract File[] getObbDirs();

    /**
     * 返回文件系统上特定于应用程序的缓存目录的绝对路径。 这些文件将在设备存储空间不足时被首先删除。 这些文件将被删除时无法保证。
     *
     * 注意：您不应该依赖系统为您删除这些文件; 对于缓存文件占用的空间量，您应始终拥有合理的最大值（例如1 MB），并在超出该空间时修剪这些文件。
     *
     * @return 保存应用程序缓存文件的目录的路径。
     *
     * @see #openFileOutput
     * @see #getFileStreamPath
     * @see #getDir
     */
    public abstract File getCacheDir();

    /**
     *返回专用于存储缓存代码的文件系统上特定于应用程序的缓存目录的绝对路径。 无论何时升级您的特定应用程序以及升级整个平台时，系统都会删除存储在此位置的所有文件。
     * 
     * 此位置适用于存储由应用程序在运行时生成的编译或优化的代码。
     * 
     * 应用程序不需要额外的权限来读取或写入返回的路径，因为此路径位于其私有存储中。
     *
     * @return 保存应用程序代码缓存文件的目录的路径。
     */
    public abstract File getCodeCacheDir();

    /**
     * 返回主外部文件系统（位于
     * {@link android.os.Environment#getExternalStorageDirectory()
     * Environment.getExternalStorageDirectory()}
     *
     * 上的某个目录的绝对路径，应用程序可以在其中放置它拥有的缓存文件 。这些文件是应用程序的内部文件，通常对用户来说不是媒体可见的，
     * 这就像{@link #getCacheDir()}，这些文件在卸载应用程序时会被删除，但是有一些重要的 不同之处：
     *
     * 1.该平台并不总是监视外部存储中可用的空间，因此可能不会自动删除这些文件。 目前这里的唯一时间文件将被平台删除，
     * 当在{@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR1} 或更高版本和
     * {@link android.os.Environment#isExternalStorageEmulated()
     * Environment.isExternalStorageEmulated()}返回true。
     * 请注意，您应该像管理{@link #getCacheDir()}一样管理您将使用的最大空间。
     *
     * 2.外部文件并不总是可用的：如果用户将外部存储装置安装在计算机上或将其移除，它们将消失。 请参阅 {@link android.os.Environment} 获取存储状态信息。
     这些文件没有执行安全措施。 例如，任何持有{@link android.Manifest.permission#WRITE_EXTERNAL_STORAGE}可以写入这些文件。

     * 
     *从{@link android.os.Build.VERSION_CODES#KITKAT}，读取或写入返回的路径不需要任何权限;
     * 它始终可供调用应用程序访问。 这仅适用于为调用应用程序的包名称生成的路径。 要访问属于其他包的路径，
     * {@link android.Manifest.permission#WRITE_EXTERNAL_STORAGE}
     * and/or {@link android.Manifest.permission#READ_EXTERNAL_STORAGE} 是必需的。
     *
     * 在具有多个用户的设备上（如{@link UserManager}所述），每个用户都有自己独立的外部存储。 应用程序只能访问运行用户的外部存储。
     *
     *
     * @return 目录在外部存储器上保存应用程序缓存文件的路径。 如果外部存储当前未安装，则返回null，因此无法确保路径存在; 当它可用时，您将需要再次调用此方法。
     *
     * @see #getCacheDir
     */
    @Nullable
    public abstract File getExternalCacheDir();

    /**
     * 返回应用程序可以放置它拥有的缓存文件的所有外部存储设备上特定于应用程序的目录的绝对路径。
     * 这些文件是应用程序的内部文件，并且通常不会作为媒体显示给用户。
     * 这就像{@link #getCacheDir()}，因为这些文件在卸载应用程序时将被删除，但是有一些重要的区别：
     *1.外部文件并不总是可用的：如果用户将外部存储装置安装在计算机上或将其移除，它们将消失。
     * 2.这些文件没有执行安全措施。
     * 
     * 这里返回的外部存储设备被视为设备的永久部分，包括仿真的外部存储和物理介质插槽
     * ，如电池仓中的SD卡。 返回的路径不包括瞬态设备，如USB闪存驱动器。
     * 应用程序可以将数据存储在任何或所有返回的设备上。 例如，应用可能会选择将大文件存储在具有最多可用空间的设备上，
     * 如{@link StatFs}所衡量的。 读取或写入返回的路径不需要任何权限;
     * 他们总是可以访问调用应用程序。 在辅助外部存储设备上写入这些路径之外的访问权限不可用。
     * 返回的第一个路径与{@link #getExternalCacheDir()}相同。 如果存储设备不可用，返回的路径可能为{null}。
     *
     * @see #getExternalCacheDir()
     * @see Environment#getExternalStorageState(File)
     */
    public abstract File[] getExternalCacheDirs();

    /**
     * 返回应用程序可放置媒体文件的所有外部存储设备上特定于应用程序的目录的绝对路径。
     * 通过{@link MediaStore}扫描这些文件并将其提供给其他应用程序。
     * 这就像{@link #getExternalFilesDirs}一样，这些文件在卸载应用程序时会被删除，但是有一些重要的区别：
     * 1.外部文件并不总是可用的：如果用户将外部存储装置安装在计算机上或将其移除，它们将消失
     * 2.这些文件没有执行安全措施
     * 
     * 这里返回的外部存储设备被视为设备的永久部分，包括仿真的外部存储和物理介质插槽，如电池仓中的SD卡。
     * 返回的路径不包括瞬态设备，如USB闪存驱动器。 应用程序可以将数据存储在任何或所有返回的设备上。
     * 例如，应用可能会选择将大文件存储在具有最多可用空间的设备上，如{@link StatFs}.所衡量的。
     * 读取或写入返回的路径不需要任何权限; 他们总是可以访问调用应用程序。
     * 在辅助外部存储设备上写入这些路径之外的访问权限不可用。 如果存储设备不可用，返回的路径可能为{null}。
     *
     *
     * @see Environment#getExternalStorageState(File)
     */
    public abstract File[] getExternalMediaDirs();

    /**
     * 返回一个字符串数组，命名与此上下文的应用程序包关联的私有文件。
     *
     * @return Array of strings naming the private files.
     *
     * @see #openFileInput
     * @see #openFileOutput
     * @see #deleteFile
     */
    public abstract String[] fileList();

    /**
     * 检索，如果需要，创建一个新的目录，其中应用程序可以放置自己的自定义数据文件。您可以使用返回的文件对象来创建和访问这个目录中的文件。
     * 注意，通过File对象创建的文件只能由您自己的应用程序访问;您只能设置整个目录的模式，而不是单个文件的。
     *
     * @param name 要检索的目录的名称。这是一个目录，它是作为应用程序数据的一部分创建的。
     * @param mode 操作模式。使用0或{@link #MODE_PRIVATE}用于默认操作，{@link # mode_world_read}和{@link #MODE_WORLD_WRITEABLE}来控制权限。
     *
     *
     * @return 请求目录的{@link文件}对象。如果目录不存在，就会创建。
     *
     * @see #openFileOutput(String, int)
     */
    public abstract File getDir(String name, int mode);

    /**
     * 打开与此上下文的*应用程序包关联的新的私有SQLiteDatabase。创建数据库文件，如果它不存在。
     *
     * @param name 数据库的名称(在应用程序包中是唯一的)。
     * @param mode 操作模式。使用0或{@link #MODE_PRIVATE}用于*默认操作，{@link # mode_world_read}
     *             和{@link #MODE_WORLD_WRITEABLE}来控制权限。
     *             *使用{@link #MODE_ENABLE_WRITE_AHEAD_LOGGING}，在默认情况下启用写前日志记录
     * @param factory 一个可选的工厂类，当查询被调用时，被调用来实例化*游标。
     *
     * @return 新创建的带有给定名称的数据库的内容。
     * @throws android.database.sqlite.SQLiteException 如果数据库文件无法打开。
     *
     * @see #MODE_PRIVATE
     * @see #MODE_WORLD_READABLE
     * @see #MODE_WORLD_WRITEABLE
     * @see #MODE_ENABLE_WRITE_AHEAD_LOGGING
     * @see #deleteDatabase
     */
    public abstract SQLiteDatabase openOrCreateDatabase(String name,
            int mode, CursorFactory factory);

    /**
     * 打开与此上下文的*应用程序包关联的新的私有SQLiteDatabase。创建数据库文件，如果它不存在。
     *
     * 接受输入param:当sqlite报告数据库损坏时，使用{@link DatabaseErrorHandler}的具体实例来处理腐败。
     *
     * @param name 数据库的名称(在应用程序包中是唯一的)。
     * @param mode 操作模式。使用0或{@link #MODE_PRIVATE}用于*默认操作，{@link # mode_world_read}
     *             和{@link #MODE_WORLD_WRITEABLE}来控制权限。*使用{@link #MODE_ENABLE_WRITE_AHEAD_LOGGING}，在默认情况下启用写前日志记录。
     * @param factory 一个可选的工厂类，当查询被调用时，被调用来实例化*游标。
     * @param errorHandler 当sqlite报告数据库* *损坏时，使用{@link DatabaseErrorHandler}。如果是null,{ @link android.database。DefaultDatabaseErrorHandler }。
     * @return 新创建的带有给定名称的数据库的内容。
     * @throws android.database.sqlite.SQLiteException 如果数据库文件无法打开。
     *
     * @see #MODE_PRIVATE
     * @see #MODE_WORLD_READABLE
     * @see #MODE_WORLD_WRITEABLE
     * @see #MODE_ENABLE_WRITE_AHEAD_LOGGING
     * @see #deleteDatabase
     */
    public abstract SQLiteDatabase openOrCreateDatabase(String name,
            int mode, CursorFactory factory,
            @Nullable DatabaseErrorHandler errorHandler);

    /**
     * 删除与此上下文的*应用程序包关联的现有私有SQLiteDatabase。
     *
     * @param name 数据库的名称(在应用程序包中是唯一的)。
     *
     * @return {@code true}如果数据库被成功删除;{ @code假}。
     *
     * @see #openOrCreateDatabase
     */
    public abstract boolean deleteDatabase(String name);

    /**
     * 返回文件系统上的绝对路径，其中存储了由* {@link #openOrCreateDatabase}创建的数据库。
     *
     * @param name 您想要获取的数据库的名称。
     *
     * @return 对给定数据库的绝对路径。
     *
     * @see #openOrCreateDatabase
     */
    public abstract File getDatabasePath(String name);

    /**
     *返回一个字符串数组，命名与*这个上下文的应用程序包关联的私有数据库。
     *
     * @return 命名私有数据库的字符串数组。
     *
     * @see #openOrCreateDatabase
     * @see #deleteDatabase
     */
    public abstract String[] databaseList();

    /**
     * @deprecated Use {@link android.app.WallpaperManager#getDrawable
     * WallpaperManager.get()} instead.
     */
    @Deprecated
    public abstract Drawable getWallpaper();

    /**
     * @deprecated Use {@link android.app.WallpaperManager#peekDrawable
     * WallpaperManager.peek()} instead.
     */
    @Deprecated
    public abstract Drawable peekWallpaper();

    /**
     * @deprecated Use {@link android.app.WallpaperManager#getDesiredMinimumWidth()
     * WallpaperManager.getDesiredMinimumWidth()} instead.
     */
    @Deprecated
    public abstract int getWallpaperDesiredMinimumWidth();

    /**
     * @deprecated Use {@link android.app.WallpaperManager#getDesiredMinimumHeight()
     * WallpaperManager.getDesiredMinimumHeight()} instead.
     */
    @Deprecated
    public abstract int getWallpaperDesiredMinimumHeight();

    /**
     * @deprecated Use {@link android.app.WallpaperManager#setBitmap(Bitmap)
     * WallpaperManager.set()} instead.
     * This method requires the caller to hold the permission
     * {@link android.Manifest.permission#SET_WALLPAPER}.
     */
    @Deprecated
    public abstract void setWallpaper(Bitmap bitmap) throws IOException;

    /**
     * @deprecated Use {@link android.app.WallpaperManager#setStream(InputStream)
     * WallpaperManager.set()} instead.
     * This method requires the caller to hold the permission
     * {@link android.Manifest.permission#SET_WALLPAPER}.
     */
    @Deprecated
    public abstract void setWallpaper(InputStream data) throws IOException;

    /**
     * @deprecated Use {@link android.app.WallpaperManager#clear
     * WallpaperManager.clear()} instead.
     * This method requires the caller to hold the permission
     * {@link android.Manifest.permission#SET_WALLPAPER}.
     */
    @Deprecated
    public abstract void clearWallpaper() throws IOException;

    /**
     * 与{@link #startActivity(Intent, Bundle)}相同，没有指定选项*。
     *
     * @param intent 开始活动的描述。
     *
     * @throws ActivityNotFoundException &nbsp;
     *
     * @see #startActivity(Intent, Bundle)
     * @see PackageManager#resolveActivity
     */
    public abstract void startActivity(Intent intent);

    /**
     * 版本的{@link #startActivity(Intent)}，允许您指定*用户的活动将被启动。在系统映像中未预先安装的应用程序无法使用此功能。使用它需要持有* INTERACT_ACROSS_USERS_FULL权限。
     * @param intent 开始活动的描述。
     * @param user 用户的用户句柄启动此活动。
     * @throws ActivityNotFoundException &nbsp;
     * @hide
     */
    public void startActivityAsUser(Intent intent, UserHandle user) {
        throw new RuntimeException("Not implemented. Must override in a subclass.");
    }

    /**
     * 推出一个新活动。您将不会收到任何关于何时*活动退出的信息。* *注意，
     * 如果这个方法是从一个{@link android.app.Activity} 上下文，然后意图必须包括 {@link Intent#FLAG_ACTIVITY_NEW_TASK}启动标志
     * 。这是因为，*没有从现有的活动开始，就没有现有的任务来放置新的活动，因此需要将它放在单独的任务中。
     * * *这个方法抛出{ @link ActivityNotFoundException } *如果没有活动发现运行给定的意图。
     *
     * @param intent 开始活动的描述。
     * @param options 如何启动活动的其他选项。*如果没有选择，可能为空。看到{ @link android.app。ActivityOptions} *关于如何构建此处提供的包;没有支持的定义*用于手动构建。
     *
     * @throws ActivityNotFoundException &nbsp;
     *
     * @see #startActivity(Intent)
     * @see PackageManager#resolveActivity
     */
    public abstract void startActivity(Intent intent, @Nullable Bundle options);

    /**
     * {@link #startActivity(Intent, Bundle)}，允许您指定*用户的活动将开始。在系统映像中未预先安装的应用程序无法使用此功能。使用它需要持有* INTERACT_ACROSS_USERS_FULL权限。
     * @param intent 开始活动的描述。
     * @param options 如何启动活动的其他选项。*如果没有选择，可能为空。看到{ @link android.app。ActivityOptions} *关于如何构建此处提供的包;没有支持的定义*用于手动构建。
     * @param userId 用户的用户句柄启动此活动。
     * @throws ActivityNotFoundException &nbsp;
     * @hide
     */
    public void startActivityAsUser(Intent intent, @Nullable Bundle options, UserHandle userId) {
        throw new RuntimeException("Not implemented. Must override in a subclass.");
    }

    /**
     * 与{@link #startActivities(Intent[]， Bundle)}相同，没有指定选项*。
     *
     * @param intents An array of Intents to be started.
     *
     * @throws ActivityNotFoundException &nbsp;
     *
     * @see #startActivities(Intent[], Bundle)
     * @see PackageManager#resolveActivity
     */
    public abstract void startActivities(Intent[] intents);

    /**
     * 启动多个新的活动。这通常是一样的叫 {@link #startActivity(Intent)} 第一意图数组中
     * ,活动期间创建调用 {@link #startActivity(Intent)}第二项,等。
     *
     * 请注意,这种方法不同,一般*数组中除了最后的活动将创建*在这一点上,而是将他们当用户第一次访问*创建(由于紧迫从活动上)。*
     * *这个方法抛出{ @link ActivityNotFoundException } *如果没有活动发现对于任何给定的意图。
     * 在这种情况下，活动堆栈的状态是未定义的(在*列表中有一些意图可能在上面，有些则没有)，所以您可能希望避免这种情况。
     *
     *
     * @param intents 一组要启动的意图。
     * @param options 如何启动活动的其他选项。
     *                See {@link android.content.Context#startActivity(Intent, Bundle)
     * Context.startActivity(Intent, Bundle)} for more details.
     *
     * @throws ActivityNotFoundException &nbsp;
     *
     * @see #startActivities(Intent[])
     * @see PackageManager#resolveActivity
     */
    public abstract void startActivities(Intent[] intents, Bundle options);

    /**
     * @hide
     * 启动多项新活动。 这通常与为数组中的第一个Intent调用
     * {@link #startActivity(Intent)} 相同，在其创建过程中为该第二个条目调用 {@link #startActivity(Intent)}
     * 等等。请注意， 与那种方法不同，通常在这一点上除了数组中的最后一个活动之外都不会创建任何活动，而是在用户第一次访问它们时（由于顶部的活动压回来）而创建。
     * 
     * 如果没有找到任何给定Intent的活动，则此方法会抛出{@link ActivityNotFoundException}
     * 在这种情况下，活动堆栈的状态是未定义的（列表中的一些Intents可能在其上，有些不是），所以您可能想要避免这种情况。
     *
     *
     * @param intents 要开始的一系列意向。
     * @param options 应该如何开始活动的附加选项
     * @param userHandle 要为其启动活动的用户
     * See {@link android.content.Context#startActivity(Intent, Bundle)
     * Context.startActivity(Intent, Bundle)} for more details.
     *
     * @throws ActivityNotFoundException &nbsp;
     *
     * @see #startActivities(Intent[])
     * @see PackageManager#resolveActivity
     */
    public void startActivitiesAsUser(Intent[] intents, Bundle options, UserHandle userHandle) {
        throw new RuntimeException("Not implemented. Must override in a subclass.");
    }

    /**
     * 与{@link #startIntentSender(IntentSender, Intent, int, int, int, Bundle)}相同，没有指定任何选项。
     *
     * @param intent 意图发件人启动。
     * @param fillInIntent 如果非null，则将作为intent参数提供给{@link IntentSender#sendIntent}.
     * @param flagsMask 您想要更改的原始意图发件人中的意图标志。
     * @param flagsValues 在标志Mask中设置的任何位的期望值
     * @param extraFlags 始终设置为0。
     *
     * @see #startActivity(Intent)
     * @see #startIntentSender(IntentSender, Intent, int, int, int, Bundle)
     */
    public abstract void startIntentSender(IntentSender intent,
            Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags)
            throws IntentSender.SendIntentException;

    /**
     * 像{@link #startActivity(Intent, Bundle)}一样，但要启动一个Intent发件人。 
     * 如果意图发件人用于某个活动，那么该活动将以您在此处调用常规 {@link #startActivity(Intent)}开始; 否则，其相关操作将被执行（例如发送广播），
     * 就像您已经在其上调用了{@link IntentSender#sendIntent IntentSender.sendIntent} 一样。
     * 
     * 
     *
     * @param intent 意图发件人启动
     * @param fillInIntent 如果非null，则将作为intent参数提供给{@link IntentSender#sendIntent}.
     * @param flagsMask 您想要更改的原始意图发件人中的意图标志
     * @param flagsValues 在标志Mask中设置的任何位的期望值
     * @param extraFlags 始终设置为0。
     * @param options 应该如何开始活动的附加选项。 请参阅{@link android.content.Context#startActivity(Intent, Bundle)
     * Context.startActivity(Intent, Bundle)} 
     *                以获取更多详细信息。 如果意向发件人也提供了选项，则此处给出的选项将覆盖与意图发件人给出的任何冲突。
     * 
     *
     * @see #startActivity(Intent, Bundle)
     * @see #startIntentSender(IntentSender, Intent, int, int, int)
     */
    public abstract void startIntentSender(IntentSender intent,
            @Nullable Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags,
            Bundle options) throws IntentSender.SendIntentException;

    /**
     * 将给定的意图广播给所有感兴趣的广播接收机。 这个调用是异步的; 它会立即返回，并且您将在接收器运行时继续执行。
     * 没有结果从接收器传播，接收器不能中止广播。 如果您希望允许接收者传播结果或中止广播，
     * 则必须使用{@link #sendOrderedBroadcast(Intent, String)}.发送有序广播。
     * 
     *
     * 有关意向广播的更多信息，请参阅{@link BroadcastReceiver} 
     *
     * @param intent 广播意图; 所有匹配此Intent的接收器都将收到广播。
     *
     * @see android.content.BroadcastReceiver
     * @see #registerReceiver
     * @see #sendBroadcast(Intent, String)
     * @see #sendOrderedBroadcast(Intent, String)
     * @see #sendOrderedBroadcast(Intent, String, BroadcastReceiver, Handler, int, String, Bundle)
     */
    public abstract void sendBroadcast(Intent intent);

    /**
     * 将给定的意向广播给所有感兴趣的广播接收器，允许强制执行可选的必需许可。 这个调用是异步的; 它会立即返回，
     * 并且您将在接收器运行时继续执行。 没有结果从接收器传播，接收器不能中止广播。 如果您希望允许接收者传播结果或中止广播，
     * 则必须使用{@link #sendOrderedBroadcast(Intent, String)}.发送有序广播。
     * 
     *
     * See {@link BroadcastReceiver} for more information on Intent broadcasts.
     *
     * @param intent 广播意图; 所有匹配此Intent的接收器都将收到广播
     * @param receiverPermission （可选）字符串命名接收方为了接收广播而必须持有的权限。 如果为null，则不需要权限。
     *
     * @see android.content.BroadcastReceiver
     * @see #registerReceiver
     * @see #sendBroadcast(Intent)
     * @see #sendOrderedBroadcast(Intent, String)
     * @see #sendOrderedBroadcast(Intent, String, BroadcastReceiver, Handler, int, String, Bundle)
     */
    public abstract void sendBroadcast(Intent intent,
            @Nullable String receiverPermission);

    /**
     * @hide 像 {@link #sendBroadcast(Intent, String)}一样，但也允许根据 {@link android.app.AppOpsManager}。
     */
    public abstract void sendBroadcast(Intent intent,
            String receiverPermission, int appOp);

    /**
     * 将给定的意图广播给所有感兴趣的广播接收机，一次发送一个广播接收机，以便让更多偏好的接收机在将广播发送给次优先接收机之前消费广播。 这个调用是异步的; 它会立即返回，并且您将在接收器运行时继续执行。 
     *
     * See {@link BroadcastReceiver} for more information on Intent broadcasts.
     *
     * @param intent 广播意图; 所有匹配此Intent的接收器都将收到广播。
     * @param receiverPermission （可选）字符串命名接收方为了接收广播而必须拥有的权限。 如果为null，则不需要权限。
     *
     * @see android.content.BroadcastReceiver
     * @see #registerReceiver
     * @see #sendBroadcast(Intent)
     * @see #sendOrderedBroadcast(Intent, String, BroadcastReceiver, Handler, int, String, Bundle)
     */
    public abstract void sendOrderedBroadcast(Intent intent,
            @Nullable String receiverPermission);

    /**{@link #sendBroadcast(Intent)} 的版本，允许您从广播接收数据。 这是通过在调用时提供您自己的广播接收器来实现的，广播接收器将在广播结束时被视为最终接收器 - 
     * 它的{@link BroadcastReceiver#onReceive} 方法将被调用，并从另一方收集结果值 接收器。 
     * 广播将以与调用{@link #sendOrderedBroadcast(Intent, String)}相同的方式进行序列化。
     * 
     * ：像 {@link #sendBroadcast(Intent)}一样，这种方法是异步的; 它将在结果esultReceiver.onReceive() 被调用之前返回。
     *
     *
     * See {@link BroadcastReceiver} for more information on Intent broadcasts.
     *
     * @param intent 广播意图; 所有匹配此Intent的接收器都将收到广播。 
     * @param receiverPermission 字符串命名接收方为了接收广播而必须拥有的权限。 如果为null，则不需要权限。
     * @param resultReceiver 您自己的广播接收器将其视为广播的最终接收者。
     * @param scheduler 一个自定义处理程序，用它来安排结果Receiver回调; 如果为null，它将在Context的主线程中进行调度。
     * @param initialCode 果代码的初始值。 经常活动。 结果OK。
     * @param initialData 结果数据的初始值。 通常为空。
     * @param initialExtras ：结果额外的初始值。 通常为空。
     *
     * @see #sendBroadcast(Intent)
     * @see #sendBroadcast(Intent, String)
     * @see #sendOrderedBroadcast(Intent, String)
     * @see android.content.BroadcastReceiver
     * @see #registerReceiver
     * @see android.app.Activity#RESULT_OK
     */
    public abstract void sendOrderedBroadcast(@NonNull Intent intent,
            @Nullable String receiverPermission, BroadcastReceiver resultReceiver,
            @Nullable Handler scheduler, int initialCode, @Nullable String initialData,
            @Nullable Bundle initialExtras);

    /**
     * Like {@link #sendOrderedBroadcast(Intent, String, BroadcastReceiver, android.os.Handler,
     * int, String, android.os.Bundle)}, but also allows specification
     * of an associated app op as per {@link android.app.AppOpsManager}.
     * @hide
     */
    public abstract void sendOrderedBroadcast(Intent intent,
            String receiverPermission, int appOp, BroadcastReceiver resultReceiver,
            Handler scheduler, int initialCode, String initialData,
            Bundle initialExtras);

    /**
     *  {@link #sendBroadcast(Intent)}的版本，允许您指定广播将被发送到的用户。 这不适用于系统映像上未预安装的应用程序。 使用它需要持有INTERACT ACROSS USERS权限。
     * 
     * @param user 用户手柄将意图发送给
     * @see #sendBroadcast(Intent)
     */
    public abstract void sendBroadcastAsUser(Intent intent, UserHandle user);

    /**
     * {@link #sendBroadcast(Intent, String)}的版本，允许您指定广播将被发送到的用户。 这不适用于系统映像上未预安装的应用程序。 使用它需要持有INTERACT ACROSS USERS权限。
     * 
     *
     * @param intent 广播意图; 所有匹配此Intent的接收器都将收到广播
     * @param user 用户手柄将意图发送给
     * @param receiverPermission （可选）字符串命名接收方为了接收广播而必须持有的权限。 如果为null，则不需要权限。
     *
     * @see #sendBroadcast(Intent, String)
     */
    public abstract void sendBroadcastAsUser(Intent intent, UserHandle user,
            @Nullable String receiverPermission);

    /**
     * {@link #sendOrderedBroadcast(Intent, String, BroadcastReceiver, Handler, int, String, Bundle)}的版本，允许您指定广播将被发送到的用户。
     * 这不适用于系统映像上未预安装的应用程序。 使用它需要持有INTERACT ACROSS USERS权限。
     * 
     *
     * See {@link BroadcastReceiver} for more information on Intent broadcasts.
     *
     * @param intent 广播意图; 所有匹配此Intent的接收器都将收到广播。
     * @param user 用户手柄将意图发送给。
     * @param receiverPermission 字符串命名接收方为了接收广播而必须拥有的权限。 如果为null，则不需要权限。
     * @param resultReceiver 您自己的广播接收器将其视为广播的最终接收者。
     * @param scheduler 一个自定义处理程序，用它来安排结果Receiver回调; 如果为null，它将在Context的主线程中进行调度。
     * @param initialCode 结果代码的初始值。  Often Activity.RESULT_OK.
     * @param initialData 结果数据的初始值。 通常为空。
     * @param initialExtras 结果额外的初始值。 通常为空
     *
     * @see #sendOrderedBroadcast(Intent, String, BroadcastReceiver, Handler, int, String, Bundle)
     */
    public abstract void sendOrderedBroadcastAsUser(Intent intent, UserHandle user,
            @Nullable String receiverPermission, BroadcastReceiver resultReceiver,
            @Nullable Handler scheduler, int initialCode, @Nullable String initialData,
            @Nullable  Bundle initialExtras);

    /**
     * 与上述类似，但也需要应用操作，以执行限制。
     * @see #sendOrderedBroadcastAsUser(Intent, UserHandle, String,
     *       BroadcastReceiver, Handler, int, String, Bundle)
     * @hide
     */
    public abstract void sendOrderedBroadcastAsUser(Intent intent, UserHandle user,
            @Nullable String receiverPermission, int appOp, BroadcastReceiver resultReceiver,
            @Nullable Handler scheduler, int initialCode, @Nullable String initialData,
            @Nullable  Bundle initialExtras);

    /**
     * 执行“sticky”的{@link #sendBroadcast(Intent)} ，这意味着您发送的Intent在广播完成后仍处于停留状态，
     * 以便其他人可以通过返回值{@link #registerReceiver(BroadcastReceiver, IntentFilter)}。
     * 在所有其他方面，这表现与{@link #sendBroadcast(Intent)}相同。
     * 
     * 
     *你必须持有 {@link android.Manifest.permission#BROADCAST_STICKY}权限才能使用此API。 如果您未拥有该权限，则会抛出{@link SecurityException}。
     * 
     *
     * @deprecated 不应使用粘滞广播。 它们不提供安全性（任何人都可以访问它们），
     * 没有保护（任何人都可以修改它们）以及其他许多问题。 推荐的模式是使用非粘性广播来报告某些事情已经发生变化，另一种机制是应用程序在需要时检索当前值。
     *
     * @param intent 广播意图; 所有与此Intent匹配的接收器都将接收到广播，并且该意向将被重新广播给未来的接收器。
     *
     * @see #sendBroadcast(Intent)
     * @see #sendStickyOrderedBroadcast(Intent, BroadcastReceiver, Handler, int, String, Bundle)
     */
    @Deprecated
    public abstract void sendStickyBroadcast(Intent intent);

    /**
     *  {@link #sendStickyBroadcast} 的版本，可让您从广播中接收数据。 
     * 这是通过在调用时提供您自己的广播接收器来实现的，广播接收器将在广播结束时被视为最终接收器 - 
     * 它的{@link BroadcastReceiver#onReceive}方法将被调用，并从另一方收集结果值 接收器。
     * 广播将以与调用{@link #sendOrderedBroadcast(Intent, String)}相同的方式进行序列化。
     * 
     * 
     * 像{@link #sendBroadcast(Intent)}一样，这种方法是异步的; 它将在结果resultReceiver.onReceive()被调用之前返回。 请注意，存储的粘性数据只是您最初提供给广播的数据，而不是接收机所做的任何更改。 
     *
     *
     * See {@link BroadcastReceiver} for more information on Intent broadcasts.
     *
     * @deprecated 不应使用粘滞广播。 它们不提供安全性（任何人都可以访问它们），没有保护（任何人都可以修改它们）以及其他许多问题。
     * 推荐的模式是使用非粘性广播来报告某些事情已经发生变化，另一种机制是应用程序在需要时检索当前值。
     *
     * @param intent 广播意图; 所有匹配此Intent的接收器都将收到广播
     * @param resultReceiver 您自己的广播接收器将其视为广播的最终接收者。
     * @param scheduler 一个自定义处理程序，用它来安排结果Receiver回调; 如果为null，它将在Context的主线程中进行调度。 
     * @param initialCode 结果代码的初始值.  Often
     *                    Activity.RESULT_OK.
     * @param initialData 结果数据的初始值。 通常为空。
     * @param initialExtras 结果额外的初始值。 通常为空。
     *
     * @see #sendBroadcast(Intent)
     * @see #sendBroadcast(Intent, String)
     * @see #sendOrderedBroadcast(Intent, String)
     * @see #sendStickyBroadcast(Intent)
     * @see android.content.BroadcastReceiver
     * @see #registerReceiver
     * @see android.app.Activity#RESULT_OK
     */
    @Deprecated
    public abstract void sendStickyOrderedBroadcast(Intent intent,
            BroadcastReceiver resultReceiver,
            @Nullable Handler scheduler, int initialCode, @Nullable String initialData,
            @Nullable Bundle initialExtras);

    /**
     * 删除之前使用{@link #sendStickyBroadcast}发送的数据，这样就好像粘性广播从未发生过一样。 
     * 
     *
     * 你必须持有 {@link android.Manifest.permission#BROADCAST_STICKY}权限才能使用此API。 如果您未拥有该权限，则会抛出@link SecurityException}。
     * 
     *
     * @deprecated 不应使用粘滞广播。 它们不提供安全性（任何人都可以访问它们），没有保护（任何人都可以修改它们）以及其他许多问题。
     * 推荐的模式是使用非粘性广播来报告某些事情已经发生变化，另一种机制是应用程序在需要时检索当前值
     *
     * @param intent 之前播出的意图。
     *
     * @see #sendStickyBroadcast
     */
    @Deprecated
    public abstract void removeStickyBroadcast(Intent intent);

    /**
     *{@link #sendStickyBroadcast(Intent)} 的版本，允许您指定广播将被发送到的用户。 这不适用于系统映像上未预安装的应用程序。 使用它需要持有INTERACT ACROSS USERS权限。
     *
     *
     * @deprecated 不应使用粘滞广播。 它们不提供安全性（任何人都可以访问它们），
     * 没有保护（任何人都可以修改它们）以及其他许多问题。 推荐的模式是使用非粘性广播来报告某些事情已经发生变化，另一种机制是应用程序在需要时检索当前值。 
     *
     * @param intent 广播意图; 所有与此Intent匹配的接收器都将接收到广播，并且该意向将被重新广播给未来的接收器。 
     * @param user 用户手柄将意图发送给
     *
     * @see #sendBroadcast(Intent)
     */
    @Deprecated
    public abstract void sendStickyBroadcastAsUser(Intent intent, UserHandle user);

    /**{@link #sendStickyOrderedBroadcast(Intent, BroadcastReceiver, Handler, int, String, Bundle)}允许您指定广播将被发送到的用户。
     *  这不适用于系统映像上未预安装的应用程序。 使用它需要持有INTERACT ACROSS USERS权限。
     *
     *
     * See {@link BroadcastReceiver} for more information on Intent broadcasts.
     *
     * @deprecated 不应使用粘滞广播。 它们不提供安全性（任何人都可以访问它们），
     * 没有保护（任何人都可以修改它们）以及其他许多问题。 推荐的模式是使用非粘性广播来报告某些事情已经发生变化，另一种机制是应用程序在需要时检索当前值。 
     *
     * @param intent 广播意图; 所有匹配此Intent的接收器都将收到广播。 
     * @param user 用户手柄将意图发送给
     * @param resultReceiver 您自己的广播接收器将其视为广播的最终接收者。
     * @param scheduler 个自定义处理程序，用它来安排结果Receiver回调; 如果为null，它将在Context的主线程中进行调度。
     * @param initialCode 结果代码的初始值。 Often
     *                    Activity.RESULT_OK.
     * @param initialData 结果数据的初始值。 通常为空。
     * @param initialExtras 结果额外的初始值。 通常为空。
     *
     * @see #sendStickyOrderedBroadcast(Intent, BroadcastReceiver, Handler, int, String, Bundle)
     */
    @Deprecated
    public abstract void sendStickyOrderedBroadcastAsUser(Intent intent,
            UserHandle user, BroadcastReceiver resultReceiver,
            @Nullable Handler scheduler, int initialCode, @Nullable String initialData,
            @Nullable Bundle initialExtras);

    /**
     * {@link #removeStickyBroadcast(Intent)}版本，允许您指定广播将被发送到的用户。 这不适用于系统映像上未预安装的应用程序。 使用它需要持有INTERACT ACROSS USERS权限。 
     * 
     * 你必须持有{@link android.Manifest.permission#BROADCAST_STICKY}权限才能使用此API。 如果您未拥有该权限，则会抛出{@link SecurityException}。
     *
     *
     * @deprecated 不应使用粘滞广播。 它们不提供安全性（任何人都可以访问它们），
     * 没有保护（任何人都可以修改它们）以及其他许多问题。 推荐的模式是使用非粘性广播来报告某些事情已经发生变化，另一种机制是应用程序在需要时检索当前值。
     *
     * @param intent ：之前播出的意图。
     * @param user 用户句柄以从中删除粘性广播。
     *
     * @see #sendStickyBroadcastAsUser
     */
    @Deprecated
    public abstract void removeStickyBroadcastAsUser(Intent intent, UserHandle user);

    /**
     * 注册广播接收器以在主要活动线程中运行。 在主应用程序线程中，将使用与过滤器匹配的任何广播Intent调用接收器。 
     *
     * 系统可能会广播“粘性”的内容 - 在广播结束后，这些内容将保留下来，以便发送给任何以后的注册。
     * 如果您的意图过滤器匹配其中一个粘性意图，那么该意图将由该功能返回并发送给您的接收器（如果它刚被广播）。
     * 可能有多个匹配过滤器的粘性内容，在这种情况下，每个内容都将被发送到接收方。 在这种情况下，函数只能直接返回其中的一个; 
     * 哪些返回是由系统任意决定的。 如果您知道您注册的意图是粘性的，您可以为您的接收器提供空值。
     * 在这种情况下，没有接收者注册 - 该函数只是返回匹配过滤器的粘性Intent。 在多个匹配的情况下，应用与上述相同的规则。 
     *
     * See {@link BroadcastReceiver} for more information on Intent broadcasts.
     * 
     * 截至{@link android.os.Build.VERSION_CODES#ICE_CREAM_SANDWICH}，
     * 使用此方法注册的接收方将正确地遵守为正在广播的Intent指定的{@link Intent#setPackage(String)}。 
     * 在此之前，它将被忽略并交付给所有匹配的注册接收者。 如果使用它来保证安全，请小心。
     * 
     *注意：此方法不能从{@link Broadcast Receiver}组件调用; 也就是从应用程序清单中声明的​​广播接收器。 
     * 但是，从另一个广播接收器调用此方法是可以的，因为这种已注册的广播接收器的生存期与绑定注册它的对象绑定在一起，因此它本身已在运行时注册了{@link #register Receiver}。
     * 
     
     *
     * @param receiver 广播接收器处理广播。
     * @param filter 选择要接收的意图广播。
     *
     * @return 第一个粘性意图发现匹配过滤器，如果没有，则返回null。
     *
     * @see #registerReceiver(BroadcastReceiver, IntentFilter, String, Handler)
     * @see #sendBroadcast
     * @see #unregisterReceiver
     */
    
    @Nullable
    public abstract Intent registerReceiver(@Nullable BroadcastReceiver receiver,
                                            IntentFilter filter);

    /**
     * 注册以接收意图广播，以在调度程序的上下文中运行。 有关更多信息，请参阅{@link #registerReceiver(BroadcastReceiver, IntentFilter)}。
     * 这使您可以强制谁可以向接收者广播意图，或让接收者在与主应用程序线程不同的线程中运行。 
     * 
     *
     * See {@link BroadcastReceiver} for more information on Intent broadcasts.
     *
     * 截至{@link android.os.Build.VERSION_CODES#ICE_CREAM_SANDWICH}
     * ，使用此方法注册的接收方将正确地遵守为正在广播的Intent指定的{@link Intent＃set Package（String）}。
     * 在此之前，它将被忽略并交付给所有匹配的注册接收者。 如果使用它来保证安全，请小心。
     * 
     *
     * @param receiver 广播接收器处理广播
     * @param filter 选择要接收的意图广播。
     * @param broadcastPermission 字符串命名一个*广播必须持有的权限，以便发送一个意图给你。如果是null，则不需要权限。
     * @param scheduler 处理将接收到的线程的处理程序。如果为null，则将使用该流程的主线程。
     *
     * @return 第一个粘性的意图发现匹配过滤器，*或null如果没有。
     *
     * @see #registerReceiver(BroadcastReceiver, IntentFilter)
     * @see #sendBroadcast
     * @see #unregisterReceiver
     */
    @Nullable
    public abstract Intent registerReceiver(BroadcastReceiver receiver,
            IntentFilter filter, @Nullable String broadcastPermission,
            @Nullable Handler scheduler);

    /**
     * @hide
     * 与{@link #registerReceiver(BroadcastReceiver, IntentFilter, String, Handler)}相同，但对于特定的用户。
     * 这个接收器将接收到发送到请求用户的广播。它*需要持有 {@link android.Manifest.permission#INTERACT_ACROSS_USERS_FULL}*许可。*
     * 
     * 
     *
     * @param receiver 广播接收器处理广播。
     * @param user UserHandle将意图发送到。
     * @param filter 选择要接收的意图广播。
     * @param broadcastPermission 字符串命名一个*广播必须持有的权限，以便发送一个意图给你。如果是null，则不需要权限。
     * @param scheduler 处理将接收到的线程的处理程序。如果为null，则将使用该流程的主线程。
     *
     * @return 第一个粘性的意图发现匹配过滤器，*或null如果没有。
     *
     * @see #registerReceiver(BroadcastReceiver, IntentFilter, String, Handler
     * @see #sendBroadcast
     * @see #unregisterReceiver
     */
    @Nullable
    public abstract Intent registerReceiverAsUser(BroadcastReceiver receiver,
            UserHandle user, IntentFilter filter, @Nullable String broadcastPermission,
            @Nullable Handler scheduler);

    /**
     * 注销以前注册的广播接收器。所有已为这个广播接收器注册的过滤器将被删除。
     *
     * @param receiver BroadcastReceiver注销。
     *
     * @see #registerReceiver
     */
    public abstract void unregisterReceiver(BroadcastReceiver receiver);

    /**
     * 请求启动给定的应用程序服务。Intent *应该包含包含特定服务*实现的完整类名*实现，
     * 或针对目标的特定包名。如果*意图没有被指定，它就会记录一个关于这个的警告，
     * 并且它找到和使用的多个匹配服务中的哪个将没有定义。如果这个服务*还没有运行，
     * 它将被实例化并启动(如果需要，为它创建一个*进程);如果它正在运行，那么它仍然在运行。
     * 
     *对该方法的每一个调用都会导致相应的调用*目标服务的 {@link android.app.Service#onStartCommand}方法，
     * *与这里的intentgiven。这提供了一种方便的方式，可以将作业提交给服务，而不必绑定和调用它的*接口。
     * 
     * 使用startService()覆盖了由{@link #bindService}管理的缺省服务生命周期:它要求服务保持*运行直到调用{@link #stopService}，
     * 不管是否有任何客户端连接到它。注意，调用startService() *不是嵌套:不管您调用startService()多少次，*一次调用{@link #stopService}将停止它。
     * 
     * 该系统试图尽可能地保持运行服务的运行。它们唯一应该停止的时间是，如果当前的前景应用程序使用了大量的资源，服务需要被杀死。如果在服务的过程中发生错误，它将自动重新启动。
     *
     * 此函数将抛出{@link SecurityException}，如果您没有获得启动给定服务的权限。
     *
     * @param service 标识要启动的服务。意图必须是完全显式的(提供组件名称)或指定指定的包*名称。附加的值*可能包含在意图附加项中，以提供与*这个特定的开始调用一起的参数。
     *
     * @return 如果服务正在启动或已经在运行，则启动的实际服务的* {@link ComponentName}将返回;如果服务不存在，则返回null。
     *
     * @throws SecurityException &nbsp;
     *
     * @see #stopService
     * @see #bindService
     */
    @Nullable
    public abstract ComponentName startService(Intent service);

    /**
     * 请求停止给定的应用程序服务。如果服务没有运行，什么也不会发生。否则它停止。注意，调用*对startService()没有计算——这将停止服务，无论它启动了多少次。
     *
     * 请注意，如果停止服务仍然有{@link ServiceConnection} 
     * *对象绑定到{@link #BIND_AUTO_CREATE}，它将不会被销毁，直到所有这些绑定被删除为止。
     * 
     * 参见{@link android.app.Service} 有关服务生命周期的更多详细信息的文档。
     * 
     *
     * 此函数将抛出{@link SecurityException}，如果您没有权限停止给定的服务。
     *
     * @param service 要停止服务的描述。意图必须是完全显式的(提供组件名称)或指定指定的包*名称。
     *
     * @return 果有一个服务与已经运行的给定意图相匹配，那么它就会停止，并返回{@code true};其他{@code false}被返回。
     *
     * @throws SecurityException &nbsp;
     *
     * @see #startService
     */
    public abstract boolean stopService(Intent service);

    /**
     * @hide 比如{@link #startService(Intent)}，但是对于特定的用户。
     */
    public abstract ComponentName startServiceAsUser(Intent service, UserHandle user);

    /**
     * @hide 类似{@link #stopService(Intent)}，但对于特定的用户。
     */
    public abstract boolean stopServiceAsUser(Intent service, UserHandle user);

    /**
     * 连接到应用程序服务，如果需要，创建它。这定义了应用程序和服务之间的依赖关系。给定的* 
     * connwill在创建时接收服务对象，并被告知它是否已死并重新启动。只要调用上下文存在，
     * 该服务将被系统认为是必需的*。例如，如果此上下文是停止的活动，则服务将不会被要求继续运行，直到恢复活动为止。
     * 
     *
     *如果您不允许绑定到给定的服务，此函数将抛出{@link SecurityException}。
     *
     * 注意:此方法不能从*  {@link BroadcastReceiver}组件调用。您可以使用从广播接收器到服务进行通信的模式是调用*
     * {@link #startService}，其参数包含要被发送的命令，服务调用它的*
     * {@link android.app.Service#stopSelf(int)}方法执行*该命令。
     * 请参阅API演示应用程序/服务/服务启动参数*控制器来说明这一点。但是，
     * 使用* {@link #registerReceiver}注册的广播接收器的这个方法是可以的，
     * 因为这个广播接收器的生命周期与另一个对象(注册它的对象)绑定在一起。
     * 
     *
     * @param service 标识连接到的服务。意图可以*指定一个显式组件名，或一个逻辑*描述(操作、类别等)以匹配服务发布的* {@link IntentFilter}。
     * @param conn 当服务启动和停止时接收信息。*这必须是一个有效的ServiceConnection对象;它不能为空。
     * @param flags 绑定的操作选项。可能是0，* {@link #BIND_AUTO_CREATE}， {@link #BIND_DEBUG_UNBIND}，
     * {@link # bind_not_}， {@link #BIND_ABOVE_CLIENT}， {@link #BIND_ALLOW_OOM_MANAGEMENT}，或* {@link #BIND_WAIVE_PRIORITY}。
     *              
     * @return 如果已成功绑定到服务，则返回{@code true};* {@code false}如果连接未完成，则返回，因此您将不会收到服务对象。
     *
     * @throws SecurityException &nbsp;
     *
     * @see #unbindService
     * @see #startService
     * @see #BIND_AUTO_CREATE
     * @see #BIND_DEBUG_UNBIND
     * @see #BIND_NOT_FOREGROUND
     */
    public abstract boolean bindService(Intent service, @NonNull ServiceConnection conn,
            @BindServiceFlags int flags);

    /**
     * 与{@link #bindService(Intent, ServiceConnection, int)}相同，但有一个显式userHandle *参数，供系统服务器和其他多用户感知代码使用。
     * @hide
     */
    @SystemApi
    public boolean bindServiceAsUser(Intent service, ServiceConnection conn, int flags, UserHandle user) {
        throw new RuntimeException("Not implemented. Must override in a subclass.");
    }

    /**
     * 断开与应用程序服务的连接。当服务重新启动时，您将不再接收*调用，服务现在可以在任何时候停止。
     *
     * @param conn 之前提供给* bindService()的连接接口。这个参数不能为空。
     *
     * @see #bindService
     */
    public abstract void unbindService(@NonNull ServiceConnection conn);

    /**
     * 开始执行 {@link android.app.Instrumentation} 类。给定的*仪表组件将通过杀死其目标应用程序*(如果当前正在运行)，启动目标进程，实例化*仪表组件，然后让它驱动应用程序运行。
     * 
     *这个函数不是同步的——它在*工具启动时和运行时返回。* *仪器通常只允许对一个包进行运行，该包要么是未签名的，要么是签名的，这是与设备包同时签署的(确保目标*信任该仪器)。
     *
     * @param className 要运行的仪表组件的名称。
     * @param profileFile 可选的路径，以编写分析数据作为*工具运行，或为无配置。
     * @param arguments 附加的可选参数传递给*插装，或null。
     *
     * 如果工具成功启动，如果没有找到，则返回{@code false}。
     */
    public abstract boolean startInstrumentation(@NonNull ComponentName className,
            @Nullable String profileFile, @Nullable Bundle arguments);

    /** @hide */
    @StringDef({
            POWER_SERVICE,
            WINDOW_SERVICE,
            LAYOUT_INFLATER_SERVICE,
            ACCOUNT_SERVICE,
            ACTIVITY_SERVICE,
            ALARM_SERVICE,
            NOTIFICATION_SERVICE,
            ACCESSIBILITY_SERVICE,
            CAPTIONING_SERVICE,
            KEYGUARD_SERVICE,
            LOCATION_SERVICE,
            //@hide: COUNTRY_DETECTOR,
            SEARCH_SERVICE,
            SENSOR_SERVICE,
            STORAGE_SERVICE,
            WALLPAPER_SERVICE,
            VIBRATOR_SERVICE,
            //@hide: STATUS_BAR_SERVICE,
            CONNECTIVITY_SERVICE,
            //@hide: UPDATE_LOCK_SERVICE,
            //@hide: NETWORKMANAGEMENT_SERVICE,
            //@hide: NETWORK_STATS_SERVICE,
            //@hide: NETWORK_POLICY_SERVICE,
            WIFI_SERVICE,
            WIFI_PASSPOINT_SERVICE,
            WIFI_P2P_SERVICE,
            WIFI_SCANNING_SERVICE,
            //@hide: ETHERNET_SERVICE,
            WIFI_RTT_SERVICE,
            NSD_SERVICE,
            AUDIO_SERVICE,
            MEDIA_ROUTER_SERVICE,
            TELEPHONY_SERVICE,
            TELECOM_SERVICE,
            CLIPBOARD_SERVICE,
            INPUT_METHOD_SERVICE,
            TEXT_SERVICES_MANAGER_SERVICE,
            APPWIDGET_SERVICE,
            //@hide: BACKUP_SERVICE,
            DROPBOX_SERVICE,
            DEVICE_POLICY_SERVICE,
            UI_MODE_SERVICE,
            DOWNLOAD_SERVICE,
            NFC_SERVICE,
            BLUETOOTH_SERVICE,
            //@hide: SIP_SERVICE,
            USB_SERVICE,
            LAUNCHER_APPS_SERVICE,
            //@hide: SERIAL_SERVICE,
            INPUT_SERVICE,
            DISPLAY_SERVICE,
            //@hide: SCHEDULING_POLICY_SERVICE,
            USER_SERVICE,
            //@hide: APP_OPS_SERVICE
            CAMERA_SERVICE,
            PRINT_SERVICE,
            MEDIA_SESSION_SERVICE,
            BATTERY_SERVICE,
            JOB_SCHEDULER_SERVICE,
    })
    @Retention(RetentionPolicy.SOURCE)
    public @interface ServiceName {}

    /**
     * 注:通过该API获得的系统服务可能与获得它们的上下文密切相关。一般来说，不要在不同的上下文(活动、应用程序、*服务、提供者等)之间共享*服务对象。
     *
     * @param name 所需服务的名称。
     *
     * @return 如果名称不存在，则服务或null。
     *
     * @see #WINDOW_SERVICE
     * @see android.view.WindowManager
     * @see #LAYOUT_INFLATER_SERVICE
     * @see android.view.LayoutInflater
     * @see #ACTIVITY_SERVICE
     * @see android.app.ActivityManager
     * @see #POWER_SERVICE
     * @see android.os.PowerManager
     * @see #ALARM_SERVICE
     * @see android.app.AlarmManager
     * @see #NOTIFICATION_SERVICE
     * @see android.app.NotificationManager
     * @see #KEYGUARD_SERVICE
     * @see android.app.KeyguardManager
     * @see #LOCATION_SERVICE
     * @see android.location.LocationManager
     * @see #SEARCH_SERVICE
     * @see android.app.SearchManager
     * @see #SENSOR_SERVICE
     * @see android.hardware.SensorManager
     * @see #STORAGE_SERVICE
     * @see android.os.storage.StorageManager
     * @see #VIBRATOR_SERVICE
     * @see android.os.Vibrator
     * @see #CONNECTIVITY_SERVICE
     * @see android.net.ConnectivityManager
     * @see #WIFI_SERVICE
     * @see android.net.wifi.WifiManager
     * @see #AUDIO_SERVICE
     * @see android.media.AudioManager
     * @see #MEDIA_ROUTER_SERVICE
     * @see android.media.MediaRouter
     * @see #TELEPHONY_SERVICE
     * @see android.telephony.TelephonyManager
     * @see #INPUT_METHOD_SERVICE
     * @see android.view.inputmethod.InputMethodManager
     * @see #UI_MODE_SERVICE
     * @see android.app.UiModeManager
     * @see #DOWNLOAD_SERVICE
     * @see android.app.DownloadManager
     * @see #BATTERY_SERVICE
     * @see android.os.BatteryManager
     * @see #JOB_SCHEDULER_SERVICE
     * @see android.app.job.JobScheduler
     */
    public abstract Object getSystemService(@ServiceName @NonNull String name);

    /**
     * 使用{@link #getSystemService}来检索* {@link android.os。PowerManager}用于控制电源管理，*包括“唤醒锁”，它允许您在运行长任务时保持设备正常运行。
     */
    public static final String POWER_SERVICE = "power";

    /**
     * 使用{@link #getSystemService}来检索*{@link android.view.WindowManager} 用于访问系统窗口*管理器的窗口管理器。
     *
     *
     * @see #getSystemService
     * @see android.view.WindowManager
     */
    public static final String WINDOW_SERVICE = "window";

    /**
     * 使用{@link #getSystemService}来检索* {@link android.view.LayoutInflater}在这个*上下文中，用于膨胀布局资源的LayoutInflater}。
     *
     * @see #getSystemService
     * @see android.view.LayoutInflater
     */
    public static final String LAYOUT_INFLATER_SERVICE = "layout_inflater";

    /**
     * 使用{@link #getSystemService}来检索* {@link android.accounts.AccountManager} 在你选择的某一时刻，你的帐户经理会收到你的意图。
     *
     * @see #getSystemService
     * @see android.accounts.AccountManager
     */
    public static final String ACCOUNT_SERVICE = "account";

    /**
     * 使用{@link #getSystemService}来检索* {@link android.app。ActivityManager}用于与全局*系统状态交互。
     *
     * @see #getSystemService
     * @see android.app.ActivityManager
     */
    public static final String ACTIVITY_SERVICE = "activity";

    /**
     * 使用{@link #getSystemService}来检索* {@link android.app.AlarmManager} 在您选择的*时间内收到意图。
     *
     *
     * @see #getSystemService
     * @see android.app.AlarmManager
     */
    public static final String ALARM_SERVICE = "alarm";

    /**
     * Use with {@link #getSystemService} to retrieve a
     * {@link android.app.NotificationManager} for informing the user of
     * background events.
     *
     * @see #getSystemService
     * @see android.app.NotificationManager
     */
    public static final String NOTIFICATION_SERVICE = "notification";

    /**
     * 使用{ @link # getSystemService }检索* { @link android.view.accessibility。AccessibilityManager}用于通过注册事件侦听器为UI事件提供用户反馈。
     *
     * @see #getSystemService
     * @see android.view.accessibility.AccessibilityManager
     */
    public static final String ACCESSIBILITY_SERVICE = "accessibility";

    /**
     * 使用{ @link # getSystemService }检索* { @link android.view.accessibility。CaptioningManager}用于获取*字幕属性，并监听字幕的变化。
     *
     * @see #getSystemService
     * @see android.view.accessibility.CaptioningManager
     */
    public static final String CAPTIONING_SERVICE = "captioning";

    /**
     * 使用{@link #getSystemService}来检索*{@link android.app.NotificationManager} 控制键盘守卫NotificationManager }。
     *
     * @see #getSystemService
     * @see android.app.KeyguardManager
     */
    public static final String KEYGUARD_SERVICE = "keyguard";

    /**
     * 使用{@link #getSystemService}来检索{@link * android.location。LocationManager}用于控制位置*更新。
     *
     *
     * @see #getSystemService
     * @see android.location.LocationManager
     */
    public static final String LOCATION_SERVICE = "location";

    /**
     * 使用{@link #getSystemService}来检索* {@link android.location.CountryDetector}用于检测*用户所在的国家。
     *
     *
     * @hide
     */
    public static final String COUNTRY_DETECTOR = "country_detector";

    /**
     * 使用{@link #getSystemService}来检索{@link * android.app。SearchManager }来处理搜索。
     *
     * @see #getSystemService
     * @see android.app.SearchManager
     */
    public static final String SEARCH_SERVICE = "search";

    /**
     * Use with {@link #getSystemService} to retrieve a {@link
     * android.hardware.SensorManager} for accessing sensors.
     *
     * @see #getSystemService
     * @see android.hardware.SensorManager
     */
    public static final String SENSOR_SERVICE = "sensor";

    /**
     * Use with {@link #getSystemService} to retrieve a {@link
     * android.os.storage.StorageManager} for accessing system storage
     * functions.
     *
     * @see #getSystemService
     * @see android.os.storage.StorageManager
     */
    public static final String STORAGE_SERVICE = "storage";

    /**
     * Use with {@link #getSystemService} to retrieve a
     * com.android.server.WallpaperService for accessing wallpapers.
     *
     * @see #getSystemService
     */
    public static final String WALLPAPER_SERVICE = "wallpaper";

    /**
     * Use with {@link #getSystemService} to retrieve a {@link
     * android.os.Vibrator} for interacting with the vibration hardware.
     *
     * @see #getSystemService
     * @see android.os.Vibrator
     */
    public static final String VIBRATOR_SERVICE = "vibrator";

    /**
     * Use with {@link #getSystemService} to retrieve a {@link
     * android.app.StatusBarManager} for interacting with the status bar.
     *
     * @see #getSystemService
     * @see android.app.StatusBarManager
     * @hide
     */
    public static final String STATUS_BAR_SERVICE = "statusbar";

    /**
     * Use with {@link #getSystemService} to retrieve a {@link
     * android.net.ConnectivityManager} for handling management of
     * network connections.
     *
     * @see #getSystemService
     * @see android.net.ConnectivityManager
     */
    public static final String CONNECTIVITY_SERVICE = "connectivity";

    /**
     * Use with {@link #getSystemService} to retrieve a {@link
     * android.os.IUpdateLock} for managing runtime sequences that
     * must not be interrupted by headless OTA application or similar.
     *
     * @hide
     * @see #getSystemService
     * @see android.os.UpdateLock
     */
    public static final String UPDATE_LOCK_SERVICE = "updatelock";

    /**
     * Constant for the internal network management service, not really a Context service.
     * @hide
     */
    public static final String NETWORKMANAGEMENT_SERVICE = "network_management";

    /** {@hide} */
    public static final String NETWORK_STATS_SERVICE = "netstats";
    /** {@hide} */
    public static final String NETWORK_POLICY_SERVICE = "netpolicy";

    /**
     * Use with {@link #getSystemService} to retrieve a {@link
     * android.net.wifi.WifiManager} for handling management of
     * Wi-Fi access.
     *
     * @see #getSystemService
     * @see android.net.wifi.WifiManager
     */
    public static final String WIFI_SERVICE = "wifi";

    /**
     * Use with {@link #getSystemService} to retrieve a {@link
     * android.net.wifi.passpoint.WifiPasspointManager} for handling management of
     * Wi-Fi passpoint access.
     *
     * @see #getSystemService
     * @see android.net.wifi.passpoint.WifiPasspointManager
     * @hide
     */
    public static final String WIFI_PASSPOINT_SERVICE = "wifipasspoint";

    /**
     * Use with {@link #getSystemService} to retrieve a {@link
     * android.net.wifi.p2p.WifiP2pManager} for handling management of
     * Wi-Fi peer-to-peer connections.
     *
     * @see #getSystemService
     * @see android.net.wifi.p2p.WifiP2pManager
     */
    public static final String WIFI_P2P_SERVICE = "wifip2p";

    /**
     * Use with {@link #getSystemService} to retrieve a {@link
     * android.net.wifi.WifiScanner} for scanning the wifi universe
     *
     * @see #getSystemService
     * @see android.net.wifi.WifiScanner
     * @hide
     */
    @SystemApi
    public static final String WIFI_SCANNING_SERVICE = "wifiscanner";

    /**
     * Use with {@link #getSystemService} to retrieve a {@link
     * android.net.wifi.RttManager} for ranging devices with wifi
     *
     * @see #getSystemService
     * @see android.net.wifi.RttManager
     * @hide
     */
    @SystemApi
    public static final String WIFI_RTT_SERVICE = "rttmanager";

    /**
     * Use with {@link #getSystemService} to retrieve a {@link
     * android.net.EthernetManager} for handling management of
     * Ethernet access.
     *
     * @see #getSystemService
     * @see android.net.EthernetManager
     *
     * @hide
     */
    public static final String ETHERNET_SERVICE = "ethernet";

    /**
     * Use with {@link #getSystemService} to retrieve a {@link
     * android.net.nsd.NsdManager} for handling management of network service
     * discovery
     *
     * @see #getSystemService
     * @see android.net.nsd.NsdManager
     */
    public static final String NSD_SERVICE = "servicediscovery";

    /**
     * Use with {@link #getSystemService} to retrieve a
     * {@link android.media.AudioManager} for handling management of volume,
     * ringer modes and audio routing.
     *
     * @see #getSystemService
     * @see android.media.AudioManager
     */
    public static final String AUDIO_SERVICE = "audio";

    /**
     * Use with {@link #getSystemService} to retrieve a
     * {@link android.service.fingerprint.FingerprintManager} for handling management
     * of fingerprints.
     *
     * @see #getSystemService
     * @see android.app.FingerprintManager
     * @hide
     */
    public static final String FINGERPRINT_SERVICE = "fingerprint";

    /**
     * Use with {@link #getSystemService} to retrieve a
     * {@link android.media.MediaRouter} for controlling and managing
     * routing of media.
     *
     * @see #getSystemService
     * @see android.media.MediaRouter
     */
    public static final String MEDIA_ROUTER_SERVICE = "media_router";

    /**
     * Use with {@link #getSystemService} to retrieve a
     * {@link android.media.session.MediaSessionManager} for managing media Sessions.
     *
     * @see #getSystemService
     * @see android.media.session.MediaSessionManager
     */
    public static final String MEDIA_SESSION_SERVICE = "media_session";

    /**
     * Use with {@link #getSystemService} to retrieve a
     * {@link android.telephony.TelephonyManager} for handling management the
     * telephony features of the device.
     *
     * @see #getSystemService
     * @see android.telephony.TelephonyManager
     */
    public static final String TELEPHONY_SERVICE = "phone";

    /**
     * Use with {@link #getSystemService} to retrieve a
     * {@link android.telecom.TelecomManager} to manage telecom-related features
     * of the device.
     *
     * @see #getSystemService
     * @see android.telecom.TelecomManager
     */
    public static final String TELECOM_SERVICE = "telecom";

    /**
     * Use with {@link #getSystemService} to retrieve a
     * {@link android.text.ClipboardManager} for accessing and modifying
     * the contents of the global clipboard.
     *
     * @see #getSystemService
     * @see android.text.ClipboardManager
     */
    public static final String CLIPBOARD_SERVICE = "clipboard";

    /**
     * Use with {@link #getSystemService} to retrieve a
     * {@link android.view.inputmethod.InputMethodManager} for accessing input
     * methods.
     *
     * @see #getSystemService
     */
    public static final String INPUT_METHOD_SERVICE = "input_method";

    /**
     * Use with {@link #getSystemService} to retrieve a
     * {@link android.view.textservice.TextServicesManager} for accessing
     * text services.
     *
     * @see #getSystemService
     */
    public static final String TEXT_SERVICES_MANAGER_SERVICE = "textservices";

    /**
     * Use with {@link #getSystemService} to retrieve a
     * {@link android.appwidget.AppWidgetManager} for accessing AppWidgets.
     *
     * @see #getSystemService
     */
    public static final String APPWIDGET_SERVICE = "appwidget";

    /**
     * Official published name of the (internal) voice interaction manager service.
     *
     * @hide
     * @see #getSystemService
     */
    public static final String VOICE_INTERACTION_MANAGER_SERVICE = "voiceinteraction";

    /**
     * Use with {@link #getSystemService} to retrieve an
     * {@link android.app.backup.IBackupManager IBackupManager} for communicating
     * with the backup mechanism.
     * @hide
     *
     * @see #getSystemService
     */
    @SystemApi
    public static final String BACKUP_SERVICE = "backup";

    /**
     * Use with {@link #getSystemService} to retrieve a
     * {@link android.os.DropBoxManager} instance for recording
     * diagnostic logs.
     * @see #getSystemService
     */
    public static final String DROPBOX_SERVICE = "dropbox";

    /**
     * Use with {@link #getSystemService} to retrieve a
     * {@link android.app.admin.DevicePolicyManager} for working with global
     * device policy management.
     *
     * @see #getSystemService
     */
    public static final String DEVICE_POLICY_SERVICE = "device_policy";

    /**
     * Use with {@link #getSystemService} to retrieve a
     * {@link android.app.UiModeManager} for controlling UI modes.
     *
     * @see #getSystemService
     */
    public static final String UI_MODE_SERVICE = "uimode";

    /**
     * Use with {@link #getSystemService} to retrieve a
     * {@link android.app.DownloadManager} for requesting HTTP downloads.
     *
     * @see #getSystemService
     */
    public static final String DOWNLOAD_SERVICE = "download";

    /**
     * Use with {@link #getSystemService} to retrieve a
     * {@link android.os.BatteryManager} for managing battery state.
     *
     * @see #getSystemService
     */
    public static final String BATTERY_SERVICE = "batterymanager";

    /**
     * Use with {@link #getSystemService} to retrieve a
     * {@link android.nfc.NfcManager} for using NFC.
     *
     * @see #getSystemService
     */
    public static final String NFC_SERVICE = "nfc";

    /**
     * Use with {@link #getSystemService} to retrieve a
     * {@link android.bluetooth.BluetoothAdapter} for using Bluetooth.
     *
     * @see #getSystemService
     */
    public static final String BLUETOOTH_SERVICE = "bluetooth";

    /**
     * Use with {@link #getSystemService} to retrieve a
     * {@link android.net.sip.SipManager} for accessing the SIP related service.
     *
     * @see #getSystemService
     */
    /** @hide */
    public static final String SIP_SERVICE = "sip";

    /**
     * Use with {@link #getSystemService} to retrieve a {@link
     * android.hardware.usb.UsbManager} for access to USB devices (as a USB host)
     * and for controlling this device's behavior as a USB device.
     *
     * @see #getSystemService
     * @see android.hardware.usb.UsbManager
     */
    public static final String USB_SERVICE = "usb";

    /**
     * Use with {@link #getSystemService} to retrieve a {@link
     * android.hardware.SerialManager} for access to serial ports.
     *
     * @see #getSystemService
     * @see android.hardware.SerialManager
     *
     * @hide
     */
    public static final String SERIAL_SERVICE = "serial";

    /**
     * Use with {@link #getSystemService} to retrieve a
     * {@link android.hardware.hdmi.HdmiControlManager} for controlling and managing
     * HDMI-CEC protocol.
     *
     * @see #getSystemService
     * @see android.hardware.hdmi.HdmiControlManager
     * @hide
     */
    @SystemApi
    public static final String HDMI_CONTROL_SERVICE = "hdmi_control";

    /**
     * Use with {@link #getSystemService} to retrieve a
     * {@link android.hardware.input.InputManager} for interacting with input devices.
     *
     * @see #getSystemService
     * @see android.hardware.input.InputManager
     */
    public static final String INPUT_SERVICE = "input";

    /**
     * Use with {@link #getSystemService} to retrieve a
     * {@link android.hardware.display.DisplayManager} for interacting with display devices.
     *
     * @see #getSystemService
     * @see android.hardware.display.DisplayManager
     */
    public static final String DISPLAY_SERVICE = "display";

    /**
     * Use with {@link #getSystemService} to retrieve a
     * {@link android.os.UserManager} for managing users on devices that support multiple users.
     *
     * @see #getSystemService
     * @see android.os.UserManager
     */
    public static final String USER_SERVICE = "user";

    /**
     * Use with {@link #getSystemService} to retrieve a
     * {@link android.content.pm.LauncherApps} for querying and monitoring launchable apps across
     * profiles of a user.
     *
     * @see #getSystemService
     * @see android.content.pm.LauncherApps
     */
    public static final String LAUNCHER_APPS_SERVICE = "launcherapps";

    /**
     * Use with {@link #getSystemService} to retrieve a
     * {@link android.content.RestrictionsManager} for retrieving application restrictions
     * and requesting permissions for restricted operations.
     * @see #getSystemService
     * @see android.content.RestrictionsManager
     */
    public static final String RESTRICTIONS_SERVICE = "restrictions";

    /**
     * Use with {@link #getSystemService} to retrieve a
     * {@link android.app.AppOpsManager} for tracking application operations
     * on the device.
     *
     * @see #getSystemService
     * @see android.app.AppOpsManager
     */
    public static final String APP_OPS_SERVICE = "appops";

    /**
     * Use with {@link #getSystemService} to retrieve a
     * {@link android.hardware.camera2.CameraManager} for interacting with
     * camera devices.
     *
     * @see #getSystemService
     * @see android.hardware.camera2.CameraManager
     */
    public static final String CAMERA_SERVICE = "camera";

    /**
     * {@link android.print.PrintManager} for printing and managing
     * printers and print tasks.
     *
     * @see #getSystemService
     * @see android.print.PrintManager
     */
    public static final String PRINT_SERVICE = "print";

    /**
     * Use with {@link #getSystemService} to retrieve a
     * {@link android.hardware.ConsumerIrManager} for transmitting infrared
     * signals from the device.
     *
     * @see #getSystemService
     * @see android.hardware.ConsumerIrManager
     */
    public static final String CONSUMER_IR_SERVICE = "consumer_ir";

    /**
     * {@link android.app.trust.TrustManager} for managing trust agents.
     * @see #getSystemService
     * @see android.app.trust.TrustManager
     * @hide
     */
    public static final String TRUST_SERVICE = "trust";

    /**
     * Use with {@link #getSystemService} to retrieve a
     * {@link android.media.tv.TvInputManager} for interacting with TV inputs
     * on the device.
     *
     * @see #getSystemService
     * @see android.media.tv.TvInputManager
     */
    public static final String TV_INPUT_SERVICE = "tv_input";

    /**
     * {@link android.net.NetworkScoreManager} for managing network scoring.
     * @see #getSystemService
     * @see android.net.NetworkScoreManager
     * @hide
     */
    @SystemApi
    public static final String NETWORK_SCORE_SERVICE = "network_score";

    /**
     * Use with {@link #getSystemService} to retrieve a {@link
     * android.app.UsageStatsManager} for interacting with the status bar.
     *
     * @see #getSystemService
     * @see android.app.UsageStatsManager
     * @hide
     */
    public static final String USAGE_STATS_SERVICE = "usagestats";

    /**
     * Use with {@link #getSystemService} to retrieve a {@link
     * android.app.job.JobScheduler} instance for managing occasional
     * background tasks.
     * @see #getSystemService
     * @see android.app.job.JobScheduler
     */
    public static final String JOB_SCHEDULER_SERVICE = "jobscheduler";

    /**
     * Use with {@link #getSystemService} to retrieve a {@link
     * android.service.persistentdata.PersistentDataBlockManager} instance
     * for interacting with a storage device that lives across factory resets.
     *
     * @see #getSystemService
     * @see android.service.persistentdata.PersistentDataBlockManager
     * @hide
     */
    @SystemApi
    public static final String PERSISTENT_DATA_BLOCK_SERVICE = "persistent_data_block";

    /**
     * Use with {@link #getSystemService} to retrieve a {@link
     * android.media.projection.MediaProjectionManager} instance for managing
     * media projection sessions.
     * @see #getSystemService
     * @see android.media.projection.ProjectionManager
     */
    public static final String MEDIA_PROJECTION_SERVICE = "media_projection";

    /**
     * 确定在系统中运行的特定*进程和用户ID是否允许给定权限。
     *
     * @param permission 正在检查的权限的名称。
     * @param pid 正在对进程ID进行检查。必须> 0。
     * @param uid 正在检查的用户ID。uid为0是根*用户，它将通过每个权限检查。
     *
     * @return {@link PackageManager#PERMISSION_GRANTED} if the given
     * pid/uid is allowed that permission, or
     * {@link PackageManager#PERMISSION_DENIED} if it is not.
     *
     * @see PackageManager#checkPermission(String, String)
     * @see #checkCallingPermission
     */
    @PackageManager.PermissionResult
    public abstract int checkPermission(@NonNull String permission, int pid, int uid);

    /**
     * 确定您正在处理的IPC的调用过程是否被授予了特定的权限。这基本上与调用{@link #checkPermission(String, int, int)}相同，
     * 而pid和uid返回* by  {@link android.os.Binder#getCallingPid}和{@link android.os.Binder#getCallingUid}。
     * 一个重要的区别是，如果您当前没有处理IPC，这个函数*将总是失败。这样做是为了防止意外泄露权限;您可以使用{@link #checkCallingOrSelfPermission}为了避免这种保护。
     *
     * @param permission 正在检查的权限的名称。
     *
     * @return {@link PackageManager#PERMISSION_GRANTED} if the calling
     * pid/uid is allowed that permission, or
     * {@link PackageManager#PERMISSION_DENIED} if it is not.
     *
     * @see PackageManager#checkPermission(String, String)
     * @see #checkPermission
     * @see #checkCallingOrSelfPermission
     */
    @PackageManager.PermissionResult
    public abstract int checkCallingPermission(@NonNull String permission);

    /**
     * 确定IPC的调用进程或您是否获得了特定的权限。这与* {@link #checkCallingPermission}相同，除非它授予您自己的权限*如果您目前没有处理IPC。小心使用!
     * 
     * @param permission The name of the permission being checked.
     *
     * @return {@link PackageManager#PERMISSION_GRANTED} if the calling
     * pid/uid is allowed that permission, or
     * {@link PackageManager#PERMISSION_DENIED} if it is not.
     *
     * @see PackageManager#checkPermission(String, String)
     * @see #checkPermission
     * @see #checkCallingPermission
     */
    @PackageManager.PermissionResult
    public abstract int checkCallingOrSelfPermission(@NonNull String permission);

    /**
     * 如果给定的权限不允许特定的进程*和在系统中运行的用户ID，则抛出{@link SecurityException}。
     *
     * @param permission 正在检查的权限的名称。
     * @param pid 正在对进程ID进行检查。必须是0。
     * @param uid 正在检查的用户ID。uid为0是根*用户，它将通过每个权限检查。
     * @param message 消息在抛出时包含在异常中。
     *
     * @see #checkPermission(String, int, int)
     */
    public abstract void enforcePermission(
            @NonNull String permission, int pid, int uid, @Nullable String message);

    /**
     * 
     * 如果您正在处理的IPC的调用过程未被授予特定权限，则抛出{@link * SecurityException}。这基本上等同于调用* {@link #enforcePermission(String, int, int, String)}，
     * 使用{@link android.os.Binder#getCallingPid}和{@link android.os.Binder#getCallingUid}。
     * 一个重要的区别是，如果您当前没有处理IPC， *这个函数将总是抛出SecurityException
     * 。这样做是为了防止不小心泄漏权限;你可以使用{ @link #
     * 
     * 
     *
     * @param permission 正在检查的权限的名称。
     * @param message 消息在抛出时包含在异常中。
     *
     * @see #checkCallingPermission(String)
     */
    public abstract void enforceCallingPermission(
            @NonNull String permission, @Nullable String message);

    /**
     * 如果您和IPC的调用进程都没有被授予特定权限，则抛出一个* {@link SecurityException}。这与{@link
     * #enforceCallingPermission}相同，除非它授予您自己的*权限，如果您目前没有处理IPC。使用*小心!
     * 
     *
     * @param permission 正在检查的权限的名称。
     * @param message 消息在抛出时包含在异常中。
     *
     * @see #checkCallingOrSelfPermission(String)
     */
    public abstract void enforceCallingOrSelfPermission(
            @NonNull String permission, @Nullable String message);

    /**
     * 允许访问另一个包的特定Uri，无论该包是否具有访问Uri *内容提供程序的一般权限。这可以用于授予特定的临时*权限，通常是对用户交互的响应(例如，*用户打开附件，您希望其他人可以显示)。
     *
     * 通常，您应该使用
     * {@link Intent#FLAG_GRANT_READ_URI_PERMISSION
     * Intent.FLAG_GRANT_READ_URI_PERMISSION} or
     * {@link Intent#FLAG_GRANT_WRITE_URI_PERMISSION
     * Intent.FLAG_GRANT_WRITE_URI_PERMISSION}，
     * 将意图用于*启动一个活动而不是直接启动该函数。如果您直接使用这个*函数，那么当目标不再允许*访问它时，您应该确保调用* {@link #revokeUriPermission}。
     * 
     *
     * To succeed, the content provider owning the Uri must have set the
     * {@link android.R.styleable#AndroidManifestProvider_grantUriPermissions
     * grantUriPermissions} attribute in its manifest or included the
     * {@link android.R.styleable#AndroidManifestGrantUriPermission
     * grant-uri-permissions} tag.
     *
     * @param toPackage 您希望允许访问Uri的包
     * @param uri 您希望授予访问权限的Uri。
     * @param modeFlags The desired access modes.  Any combination of
     * {@link Intent#FLAG_GRANT_READ_URI_PERMISSION
     * Intent.FLAG_GRANT_READ_URI_PERMISSION},
     * {@link Intent#FLAG_GRANT_WRITE_URI_PERMISSION
     * Intent.FLAG_GRANT_WRITE_URI_PERMISSION},
     * {@link Intent#FLAG_GRANT_PERSISTABLE_URI_PERMISSION
     * Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION}, or
     * {@link Intent#FLAG_GRANT_PREFIX_URI_PERMISSION
     * Intent.FLAG_GRANT_PREFIX_URI_PERMISSION}.
     *
     * @see #revokeUriPermission
     */
    public abstract void grantUriPermission(String toPackage, Uri uri,
            @Intent.GrantUriMode int modeFlags);

    /**
     * Remove all permissions to access a particular content provider Uri
     * that were previously added with {@link #grantUriPermission}.  The given
     * Uri will match all previously granted Uris that are the same or a
     * sub-path of the given Uri.  That is, revoking "content://foo/target" will
     * revoke both "content://foo/target" and "content://foo/target/sub", but not
     * "content://foo".  It will not remove any prefix grants that exist at a
     * higher level.
     *
     * Prior to {@link android.os.Build.VERSION_CODES#LOLLIPOP}, if you did not have
     * regular permission access to a Uri, but had received access to it through
     * a specific Uri permission grant, you could not revoke that grant with this
     * function and a {@link SecurityException} would be thrown.  As of
     * {@link android.os.Build.VERSION_CODES#LOLLIPOP}, this function will not throw a security exception,
     * but will remove whatever permission grants to the Uri had been given to the app
     * (or none).
     *
     * @param uri The Uri you would like to revoke access to.
     * @param modeFlags The desired access modes.  Any combination of
     * {@link Intent#FLAG_GRANT_READ_URI_PERMISSION
     * Intent.FLAG_GRANT_READ_URI_PERMISSION} or
     * {@link Intent#FLAG_GRANT_WRITE_URI_PERMISSION
     * Intent.FLAG_GRANT_WRITE_URI_PERMISSION}.
     *
     * @see #grantUriPermission
     */
    public abstract void revokeUriPermission(Uri uri, @Intent.AccessUriMode int modeFlags);

    /**
     * Determine whether a particular process and user ID has been granted
     * permission to access a specific URI.  This only checks for permissions
     * that have been explicitly granted -- if the given process/uid has
     * more general access to the URI's content provider then this check will
     * always fail.
     *
     * @param uri The uri that is being checked.
     * @param pid The process ID being checked against.  Must be  0.
     * @param uid The user ID being checked against.  A uid of 0 is the root
     * user, which will pass every permission check.
     * @param modeFlags The type of access to grant.  May be one or both of
     * {@link Intent#FLAG_GRANT_READ_URI_PERMISSION Intent.FLAG_GRANT_READ_URI_PERMISSION} or
     * {@link Intent#FLAG_GRANT_WRITE_URI_PERMISSION Intent.FLAG_GRANT_WRITE_URI_PERMISSION}.
     *
     * @return {@link PackageManager#PERMISSION_GRANTED} if the given
     * pid/uid is allowed to access that uri, or
     * {@link PackageManager#PERMISSION_DENIED} if it is not.
     *
     * @see #checkCallingUriPermission
     */
    public abstract int checkUriPermission(Uri uri, int pid, int uid,
            @Intent.AccessUriMode int modeFlags);

    /**
     * Determine whether the calling process and user ID has been
     * granted permission to access a specific URI.  This is basically
     * the same as calling {@link #checkUriPermission(Uri, int, int,
     * int)} with the pid and uid returned by {@link
     * android.os.Binder#getCallingPid} and {@link
     * android.os.Binder#getCallingUid}.  One important difference is
     * that if you are not currently processing an IPC, this function
     * will always fail.
     *
     * @param uri The uri that is being checked.
     * @param modeFlags The type of access to grant.  May be one or both of
     * {@link Intent#FLAG_GRANT_READ_URI_PERMISSION Intent.FLAG_GRANT_READ_URI_PERMISSION} or
     * {@link Intent#FLAG_GRANT_WRITE_URI_PERMISSION Intent.FLAG_GRANT_WRITE_URI_PERMISSION}.
     *
     * @return {@link PackageManager#PERMISSION_GRANTED} if the caller
     * is allowed to access that uri, or
     * {@link PackageManager#PERMISSION_DENIED} if it is not.
     *
     * @see #checkUriPermission(Uri, int, int, int)
     */
    public abstract int checkCallingUriPermission(Uri uri, @Intent.AccessUriMode int modeFlags);

    /**
     * Determine whether the calling process of an IPC or you has been granted
     * permission to access a specific URI.  This is the same as
     * {@link #checkCallingUriPermission}, except it grants your own permissions
     * if you are not currently processing an IPC.  Use with care!
     *
     * @param uri The uri that is being checked.
     * @param modeFlags The type of access to grant.  May be one or both of
     * {@link Intent#FLAG_GRANT_READ_URI_PERMISSION Intent.FLAG_GRANT_READ_URI_PERMISSION} or
     * {@link Intent#FLAG_GRANT_WRITE_URI_PERMISSION Intent.FLAG_GRANT_WRITE_URI_PERMISSION}.
     *
     * @return {@link PackageManager#PERMISSION_GRANTED} if the caller
     * is allowed to access that uri, or
     * {@link PackageManager#PERMISSION_DENIED} if it is not.
     *
     * @see #checkCallingUriPermission
     */
    public abstract int checkCallingOrSelfUriPermission(Uri uri,
            @Intent.AccessUriMode int modeFlags);

    /**
     * Check both a Uri and normal permission.  This allows you to perform
     * both {@link #checkPermission} and {@link #checkUriPermission} in one
     * call.
     *
     * @param uri The Uri whose permission is to be checked, or null to not
     * do this check.
     * @param readPermission The permission that provides overall read access,
     * or null to not do this check.
     * @param writePermission The permission that provides overall write
     * access, or null to not do this check.
     * @param pid The process ID being checked against.  Must be  0.
     * @param uid The user ID being checked against.  A uid of 0 is the root
     * user, which will pass every permission check.
     * @param modeFlags The type of access to grant.  May be one or both of
     * {@link Intent#FLAG_GRANT_READ_URI_PERMISSION Intent.FLAG_GRANT_READ_URI_PERMISSION} or
     * {@link Intent#FLAG_GRANT_WRITE_URI_PERMISSION Intent.FLAG_GRANT_WRITE_URI_PERMISSION}.
     *
     * @return {@link PackageManager#PERMISSION_GRANTED} if the caller
     * is allowed to access that uri or holds one of the given permissions, or
     * {@link PackageManager#PERMISSION_DENIED} if it is not.
     */
    public abstract int checkUriPermission(@Nullable Uri uri, @Nullable String readPermission,
            @Nullable String writePermission, int pid, int uid,
            @Intent.AccessUriMode int modeFlags);

    /**
     * If a particular process and user ID has not been granted
     * permission to access a specific URI, throw {@link
     * SecurityException}.  This only checks for permissions that have
     * been explicitly granted -- if the given process/uid has more
     * general access to the URI's content provider then this check
     * will always fail.
     *
     * @param uri The uri that is being checked.
     * @param pid The process ID being checked against.  Must be  0.
     * @param uid The user ID being checked against.  A uid of 0 is the root
     * user, which will pass every permission check.
     * @param modeFlags The type of access to grant.  May be one or both of
     * {@link Intent#FLAG_GRANT_READ_URI_PERMISSION Intent.FLAG_GRANT_READ_URI_PERMISSION} or
     * {@link Intent#FLAG_GRANT_WRITE_URI_PERMISSION Intent.FLAG_GRANT_WRITE_URI_PERMISSION}.
     * @param message A message to include in the exception if it is thrown.
     *
     * @see #checkUriPermission(Uri, int, int, int)
     */
    public abstract void enforceUriPermission(
            Uri uri, int pid, int uid, @Intent.AccessUriMode int modeFlags, String message);

    /**
     * If the calling process and user ID has not been granted
     * permission to access a specific URI, throw {@link
     * SecurityException}.  This is basically the same as calling
     * {@link #enforceUriPermission(Uri, int, int, int, String)} with
     * the pid and uid returned by {@link
     * android.os.Binder#getCallingPid} and {@link
     * android.os.Binder#getCallingUid}.  One important difference is
     * that if you are not currently processing an IPC, this function
     * will always throw a SecurityException.
     *
     * @param uri The uri that is being checked.
     * @param modeFlags The type of access to grant.  May be one or both of
     * {@link Intent#FLAG_GRANT_READ_URI_PERMISSION Intent.FLAG_GRANT_READ_URI_PERMISSION} or
     * {@link Intent#FLAG_GRANT_WRITE_URI_PERMISSION Intent.FLAG_GRANT_WRITE_URI_PERMISSION}.
     * @param message A message to include in the exception if it is thrown.
     *
     * @see #checkCallingUriPermission(Uri, int)
     */
    public abstract void enforceCallingUriPermission(
            Uri uri, @Intent.AccessUriMode int modeFlags, String message);

    /**
     * If the calling process of an IPC or you has not been
     * granted permission to access a specific URI, throw {@link
     * SecurityException}.  This is the same as {@link
     * #enforceCallingUriPermission}, except it grants your own
     * permissions if you are not currently processing an IPC.  Use
     * with care!
     *
     * @param uri The uri that is being checked.
     * @param modeFlags The type of access to grant.  May be one or both of
     * {@link Intent#FLAG_GRANT_READ_URI_PERMISSION Intent.FLAG_GRANT_READ_URI_PERMISSION} or
     * {@link Intent#FLAG_GRANT_WRITE_URI_PERMISSION Intent.FLAG_GRANT_WRITE_URI_PERMISSION}.
     * @param message A message to include in the exception if it is thrown.
     *
     * @see #checkCallingOrSelfUriPermission(Uri, int)
     */
    public abstract void enforceCallingOrSelfUriPermission(
            Uri uri, @Intent.AccessUriMode int modeFlags, String message);

    /**
     * Enforce both a Uri and normal permission.  This allows you to perform
     * both {@link #enforcePermission} and {@link #enforceUriPermission} in one
     * call.
     *
     * @param uri The Uri whose permission is to be checked, or null to not
     * do this check.
     * @param readPermission The permission that provides overall read access,
     * or null to not do this check.
     * @param writePermission The permission that provides overall write
     * access, or null to not do this check.
     * @param pid The process ID being checked against.  Must be  0.
     * @param uid The user ID being checked against.  A uid of 0 is the root
     * user, which will pass every permission check.
     * @param modeFlags The type of access to grant.  May be one or both of
     * {@link Intent#FLAG_GRANT_READ_URI_PERMISSION Intent.FLAG_GRANT_READ_URI_PERMISSION} or
     * {@link Intent#FLAG_GRANT_WRITE_URI_PERMISSION Intent.FLAG_GRANT_WRITE_URI_PERMISSION}.
     * @param message A message to include in the exception if it is thrown.
     *
     * @see #checkUriPermission(Uri, String, String, int, int, int)
     */
    public abstract void enforceUriPermission(
            @Nullable Uri uri, @Nullable String readPermission,
            @Nullable String writePermission, int pid, int uid, @Intent.AccessUriMode int modeFlags,
            @Nullable String message);

    /** @hide */
    @IntDef(flag = true,
            value = {CONTEXT_INCLUDE_CODE, CONTEXT_IGNORE_SECURITY, CONTEXT_RESTRICTED})
    @Retention(RetentionPolicy.SOURCE)
    public @interface CreatePackageOptions {}

    /**
     * Flag for use with {@link #createPackageContext}: include the application
     * code with the context.  This means loading code into the caller's
     * process, so that {@link #getClassLoader()} can be used to instantiate
     * the application's classes.  Setting this flags imposes security
     * restrictions on what application context you can access; if the
     * requested application can not be safely loaded into your process,
     * java.lang.SecurityException will be thrown.  If this flag is not set,
     * there will be no restrictions on the packages that can be loaded,
     * but {@link #getClassLoader} will always return the default system
     * class loader.
     */
    public static final int CONTEXT_INCLUDE_CODE = 0x00000001;

    /**
     * Flag for use with {@link #createPackageContext}: ignore any security
     * restrictions on the Context being requested, allowing it to always
     * be loaded.  For use with {@link #CONTEXT_INCLUDE_CODE} to allow code
     * to be loaded into a process even when it isn't safe to do so.  Use
     * with extreme care!
     */
    public static final int CONTEXT_IGNORE_SECURITY = 0x00000002;

    /**
     * Flag for use with {@link #createPackageContext}: a restricted context may
     * disable specific features. For instance, a View associated with a restricted
     * context would ignore particular XML attributes.
     */
    public static final int CONTEXT_RESTRICTED = 0x00000004;

    /**
     * @hide Used to indicate we should tell the activity manager about the process
     * loading this code.
     */
    public static final int CONTEXT_REGISTER_PACKAGE = 0x40000000;

    /**
     * Return a new Context object for the given application name.  This
     * Context is the same as what the named application gets when it is
     * launched, containing the same resources and class loader.  Each call to
     * this method returns a new instance of a Context object; Context objects
     * are not shared, however they share common state (Resources, ClassLoader,
     * etc) so the Context instance itself is fairly lightweight.
     *
     * Throws {@link PackageManager.NameNotFoundException} if there is no
     * application with the given package name.
     *
     * Throws {@link java.lang.SecurityException} if the Context requested
     * can not be loaded into the caller's process for security reasons (see
     * {@link #CONTEXT_INCLUDE_CODE} for more information}.
     *
     * @param packageName Name of the application's package.
     * @param flags Option flags, one of {@link #CONTEXT_INCLUDE_CODE}
     *              or {@link #CONTEXT_IGNORE_SECURITY}.
     *
     * @return A {@link Context} for the application.
     *
     * @throws SecurityException &nbsp;
     * @throws PackageManager.NameNotFoundException if there is no application with
     * the given package name.
     */
    public abstract Context createPackageContext(String packageName,
            @CreatePackageOptions int flags) throws PackageManager.NameNotFoundException;

    /**
     * Similar to {@link #createPackageContext(String, int)}, but with a
     * different {@link UserHandle}. For example, {@link #getContentResolver()}
     * will open any {@link Uri} as the given user.
     *
     * @hide
     */
    public abstract Context createPackageContextAsUser(
            String packageName, int flags, UserHandle user)
            throws PackageManager.NameNotFoundException;

    /**
     * Creates a context given an {@link android.content.pm.ApplicationInfo}.
     *
     * @hide
     */
    public abstract Context createApplicationContext(ApplicationInfo application,
            int flags) throws PackageManager.NameNotFoundException;

    /**
     * Get the userId associated with this context
     * @return user id
     *
     * @hide
     */
    public abstract int getUserId();

    /**
     * Return a new Context object for the current Context but whose resources
     * are adjusted to match the given Configuration.  Each call to this method
     * returns a new instance of a Context object; Context objects are not
     * shared, however common state (ClassLoader, other Resources for the
     * same configuration) may be so the Context itself can be fairly lightweight.
     *
     * @param overrideConfiguration A {@link Configuration} specifying what
     * values to modify in the base Configuration of the original Context's
     * resources.  If the base configuration changes (such as due to an
     * orientation change), the resources of this context will also change except
     * for those that have been explicitly overridden with a value here.
     *
     * @return A {@link Context} with the given configuration override.
     */
    public abstract Context createConfigurationContext(
            @NonNull Configuration overrideConfiguration);

    /**
     * Return a new Context object for the current Context but whose resources
     * are adjusted to match the metrics of the given Display.  Each call to this method
     * returns a new instance of a Context object; Context objects are not
     * shared, however common state (ClassLoader, other Resources for the
     * same configuration) may be so the Context itself can be fairly lightweight.
     *
     * The returned display Context provides a {@link WindowManager}
     * (see {@link #getSystemService(String)}) that is configured to show windows
     * on the given display.  The WindowManager's {@link WindowManager#getDefaultDisplay}
     * method can be used to retrieve the Display from the returned Context.
     *
     * @param display A {@link Display} object specifying the display
     * for whose metrics the Context's resources should be tailored and upon which
     * new windows should be shown.
     *
     * @return A {@link Context} for the display.
     */
    public abstract Context createDisplayContext(@NonNull Display display);

    /**
     * Gets the display adjustments holder for this context.  This information
     * is provided on a per-application or activity basis and is used to simulate lower density
     * display metrics for legacy applications and restricted screen sizes.
     *
     * @param displayId The display id for which to get compatibility info.
     * @return The compatibility info holder, or null if not required by the application.
     * @hide
     */
    public abstract DisplayAdjustments getDisplayAdjustments(int displayId);

    /**
     * Indicates whether this Context is restricted.
     *
     * @return {@code true} if this Context is restricted, {@code false} otherwise.
     *
     * @see #CONTEXT_RESTRICTED
     */
    public boolean isRestricted() {
        return false;
    }
}
